vserver 2.0 rc7
[linux-2.6.git] / drivers / char / keyboard.c
index 3ad30ba..7b19e02 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/tty_flip.h>
 #include <linux/mm.h>
 #include <linux/string.h>
-#include <linux/random.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 
@@ -123,7 +122,7 @@ int shift_state = 0;
  */
 
 static struct input_handler kbd_handler;
-static unsigned long key_down[256/BITS_PER_LONG];      /* keyboard key bitmap */
+static unsigned long key_down[NBITS(KEY_MAX)];         /* keyboard key bitmap */
 static unsigned char shift_down[NR_SHIFT];             /* shift state counters.. */
 static int dead_key_next;
 static int npadch = -1;                                        /* -1 or number assembled on pad */
@@ -142,7 +141,7 @@ static struct ledptr {
 /* Simple translation table for the SysRq keys */
 
 #ifdef CONFIG_MAGIC_SYSRQ
-unsigned char kbd_sysrq_xlate[128] =
+unsigned char kbd_sysrq_xlate[KEY_MAX + 1] =
         "\000\0331234567890-=\177\t"                    /* 0x00 - 0x0f */
         "qwertyuiop[]\r\000as"                          /* 0x10 - 0x1f */
         "dfghjkl;'`\000\\zxcv"                          /* 0x20 - 0x2f */
@@ -174,7 +173,7 @@ int getkeycode(unsigned int scancode)
        if (!dev)
                return -ENODEV;
 
-       if (scancode < 0 || scancode >= dev->keycodemax)
+       if (scancode >= dev->keycodemax)
                return -EINVAL;
 
        return INPUT_KEYCODE(dev, scancode);
@@ -184,7 +183,7 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
 {
        struct list_head * node;
        struct input_dev *dev = NULL;
-       int i, oldkey;
+       unsigned int i, oldkey;
 
        list_for_each(node,&kbd_handler.h_list) {
                struct input_handle *handle = to_handle_h(node);
@@ -197,7 +196,11 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
        if (!dev)
                return -ENODEV;
 
-       if (scancode < 0 || scancode >= dev->keycodemax)
+       if (scancode >= dev->keycodemax)
+               return -EINVAL;
+       if (keycode > KEY_MAX)
+               return -EINVAL;
+       if (keycode < 0 || keycode > KEY_MAX)
                return -EINVAL;
 
        oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode);
@@ -330,7 +333,7 @@ static void applkey(struct vc_data *vc, int key, char mode)
  * in utf-8 already. UTF-8 is defined for words of up to 31 bits,
  * but we need only 16 bits here
  */
-void to_utf8(struct vc_data *vc, ushort c) 
+static void to_utf8(struct vc_data *vc, ushort c)
 {
        if (c < 0x80)
                /*  0******* */
@@ -354,7 +357,7 @@ void to_utf8(struct vc_data *vc, ushort c)
  */
 void compute_shiftstate(void)
 {
-       int i, j, k, sym, val;
+       unsigned int i, j, k, sym, val;
 
        shift_state = 0;
        memset(shift_down, 0, sizeof(shift_down));
@@ -392,10 +395,10 @@ void compute_shiftstate(void)
  * Otherwise, conclude that DIACR was not combining after all,
  * queue it and return CH.
  */
-unsigned char handle_diacr(struct vc_data *vc, unsigned char ch)
+static unsigned char handle_diacr(struct vc_data *vc, unsigned char ch)
 {
        int d = diacr;
-       int i;
+       unsigned int i;
 
        diacr = 0;
 
@@ -535,12 +538,12 @@ static void fn_send_intr(struct vc_data *vc, struct pt_regs *regs)
 
 static void fn_scroll_forw(struct vc_data *vc, struct pt_regs *regs)
 {
-       scrollfront(0);
+       scrollfront(vc, 0);
 }
 
 static void fn_scroll_back(struct vc_data *vc, struct pt_regs *regs)
 {
-       scrollback(0);
+       scrollback(vc, 0);
 }
 
 static void fn_show_mem(struct vc_data *vc, struct pt_regs *regs)
@@ -580,7 +583,7 @@ static void fn_SAK(struct vc_data *vc, struct pt_regs *regs)
         */
        if (tty)
                do_SAK(tty);
-       reset_vc(fg_console);
+       reset_vc(vc);
 }
 
 static void fn_null(struct vc_data *vc, struct pt_regs *regs)
@@ -853,18 +856,6 @@ void setledstate(struct kbd_struct *kbd, unsigned int led)
        set_leds();
 }
 
-void register_leds(struct kbd_struct *kbd, unsigned int led,
-                  unsigned int *addr, unsigned int mask)
-{
-       if (led < 3) {
-               ledptrs[led].addr = addr;
-               ledptrs[led].mask = mask;
-               ledptrs[led].valid = 1;
-               kbd->ledmode = LED_SHOW_MEM;
-       } else
-               kbd->ledmode = LED_SHOW_FLAGS;
-}
-
 static inline unsigned char getleds(void)
 {
        struct kbd_struct *kbd = kbd_table + fg_console;
@@ -925,7 +916,7 @@ DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
 /*
  * This allows a newly plugged keyboard to pick the LED state.
  */
-void kbd_refresh_leds(struct input_handle *handle)
+static void kbd_refresh_leds(struct input_handle *handle)
 {
        unsigned char leds = ledstate;
 
@@ -939,7 +930,13 @@ void kbd_refresh_leds(struct input_handle *handle)
        tasklet_enable(&keyboard_tasklet);
 }
 
-#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SUPERH)
+#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
+    defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) ||\
+    defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
+    (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC))
+
+#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
+                       ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
 
 static unsigned short x86_keycodes[256] =
        { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
@@ -1007,6 +1004,8 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
 
 #else
 
+#define HW_RAW(dev)    0
+
 #warning "Cannot generate rawmode keyboard for your architecture yet."
 
 static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
@@ -1019,7 +1018,16 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char u
 }
 #endif
 
-void kbd_keycode(unsigned int keycode, int down, struct pt_regs *regs)
+static void kbd_rawcode(unsigned char data)
+{
+       struct vc_data *vc = vc_cons[fg_console].d;
+       kbd = kbd_table + fg_console;
+       if (kbd->kbdmode == VC_RAW)
+               put_queue(vc, data);
+}
+
+static void kbd_keycode(unsigned int keycode, int down,
+                       int hw_raw, struct pt_regs *regs)
 {
        struct vc_data *vc = vc_cons[fg_console].d;
        unsigned short keysym, *key_map;
@@ -1027,9 +1035,6 @@ void kbd_keycode(unsigned int keycode, int down, struct pt_regs *regs)
        struct tty_struct *tty;
        int shift_final;
 
-       if (down != 2)
-               add_keyboard_randomness((keycode << 1) ^ down);
-
        tty = vc->vc_tty;
 
        if (tty && (!tty->driver_data)) {
@@ -1053,7 +1058,7 @@ void kbd_keycode(unsigned int keycode, int down, struct pt_regs *regs)
                return;
 #endif /* CONFIG_MAC_EMUMOUSEBTN */
 
-       if ((raw_mode = (kbd->kbdmode == VC_RAW)))
+       if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw)
                if (emulate_raw(vc, keycode, !down << 7))
                        if (keycode < BTN_MISC)
                                printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
@@ -1119,6 +1124,9 @@ void kbd_keycode(unsigned int keycode, int down, struct pt_regs *regs)
                return;
        }
 
+       if (keycode > NR_KEYS)
+               return;
+
        keysym = key_map[keycode];
        type = KTYP(keysym);
 
@@ -1148,11 +1156,12 @@ void kbd_keycode(unsigned int keycode, int down, struct pt_regs *regs)
 }
 
 static void kbd_event(struct input_handle *handle, unsigned int event_type, 
-                     unsigned int keycode, int down)
+                     unsigned int event_code, int value)
 {
-       if (event_type != EV_KEY)
-               return;
-       kbd_keycode(keycode, down, handle->dev->regs);
+       if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
+               kbd_rawcode(value);
+       if (event_type == EV_KEY)
+               kbd_keycode(event_code, value, HW_RAW(handle->dev), handle->dev->regs);
        tasklet_schedule(&keyboard_tasklet);
        do_poke_blanked_console = 1;
        schedule_console_callback();