root/drivers/char/keyboard.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kb_wait
  2. send_cmd
  3. to_utf8
  4. setkeycode
  5. getkeycode
  6. keyboard_interrupt
  7. put_queue
  8. puts_queue
  9. applkey
  10. enter
  11. caps_toggle
  12. caps_on
  13. show_ptregs
  14. hold
  15. num
  16. lastcons
  17. decr_console
  18. incr_console
  19. send_intr
  20. scroll_forw
  21. scroll_back
  22. boot_it
  23. compose
  24. spawn_console
  25. SAK
  26. do_ignore
  27. do_null
  28. do_spec
  29. do_lowercase
  30. do_self
  31. do_dead
  32. handle_diacr
  33. do_cons
  34. do_fn
  35. do_pad
  36. do_cur
  37. do_shift
  38. compute_shiftstate
  39. do_meta
  40. do_ascii
  41. do_lock
  42. send_data
  43. getledstate
  44. setledstate
  45. register_leds
  46. getleds
  47. kbd_bh
  48. kbd_init

   1 /*
   2  * linux/drivers/char/keyboard.c
   3  *
   4  * Keyboard driver for Linux v0.99 using Latin-1.
   5  *
   6  * Written for linux by Johan Myreen as a translation from
   7  * the assembly version by Linus (with diacriticals added)
   8  *
   9  * Some additional features added by Christoph Niemann (ChN), March 1993
  10  *
  11  * Loadable keymaps by Risto Kankkunen, May 1993
  12  *
  13  * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
  14  * Added decr/incr_console, dynamic keymaps, Unicode support,
  15  * dynamic function/string keys, led setting,  Sept 1994
  16  * 
  17  */
  18 
  19 #define KEYBOARD_IRQ 1
  20 
  21 #include <linux/sched.h>
  22 #include <linux/interrupt.h>
  23 #include <linux/tty.h>
  24 #include <linux/tty_flip.h>
  25 #include <linux/mm.h>
  26 #include <linux/ptrace.h>
  27 #include <linux/signal.h>
  28 #include <linux/string.h>
  29 
  30 #include <asm/bitops.h>
  31 
  32 #include "kbd_kern.h"
  33 #include "diacr.h"
  34 #include "vt_kern.h"
  35 
  36 #define SIZE(x) (sizeof(x)/sizeof((x)[0]))
  37 
  38 #define KBD_REPORT_ERR
  39 #define KBD_REPORT_UNKN
  40 /* #define KBD_IS_FOCUS_9000 */
  41 
  42 #ifndef KBD_DEFMODE
  43 #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
  44 #endif
  45 
  46 #ifndef KBD_DEFLEDS
  47 /*
  48  * Some laptops take the 789uiojklm,. keys as number pad when NumLock
  49  * is on. This seems a good reason to start with NumLock off.
  50  */
  51 #define KBD_DEFLEDS 0
  52 #endif
  53 
  54 #ifndef KBD_DEFLOCK
  55 #define KBD_DEFLOCK 0
  56 #endif
  57 
  58 /*
  59  * The default IO slowdown is doing 'inb()'s from 0x61, which should be
  60  * safe. But as that is the keyboard controller chip address, we do our
  61  * slowdowns here by doing short jumps: the keyboard controller should
  62  * be able to keep up
  63  */
  64 #define REALLY_SLOW_IO
  65 #define SLOW_IO_BY_JUMPING
  66 #include <asm/io.h>
  67 #include <asm/system.h>
  68 
  69 extern void poke_blanked_console(void);
  70 extern void ctrl_alt_del(void);
  71 extern void reset_vc(unsigned int new_console);
  72 extern void change_console(unsigned int new_console);
  73 extern void scrollback(int);
  74 extern void scrollfront(int);
  75 extern int vc_cons_allocated(unsigned int);
  76 
  77 #ifdef __i386__
  78 #define fake_keyboard_interrupt() __asm__ __volatile__("int $0x21")
  79 #else
  80 #define fake_keyboard_interrupt() do ; while (0)
  81 #endif
  82 
  83 unsigned char kbd_read_mask = 0x01;     /* modified by psaux.c */
  84 
  85 /*
  86  * global state includes the following, and various static variables
  87  * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
  88  * (last_console is now a global variable)
  89  */
  90 
  91 /* shift state counters.. */
  92 static unsigned char k_down[NR_SHIFT] = {0, };
  93 /* keyboard key bitmap */
  94 static unsigned long key_down[8] = { 0, };
  95 
  96 extern int last_console;
  97 static int want_console = -1;
  98 static int dead_key_next = 0;
  99 /* 
 100  * In order to retrieve the shift_state (for the mouse server), either
 101  * the variable must be global, or a new procedure must be created to 
 102  * return the value. I chose the former way.
 103  */
 104 /*static*/ int shift_state = 0;
 105 static int npadch = -1;                 /* -1 or number assembled on pad */
 106 static unsigned char diacr = 0;
 107 static char rep = 0;                    /* flag telling character repeat */
 108 struct kbd_struct kbd_table[MAX_NR_CONSOLES];
 109 static struct tty_struct **ttytab;
 110 static struct kbd_struct * kbd = kbd_table;
 111 static struct tty_struct * tty = NULL;
 112 
 113 /* used only by send_data - set by keyboard_interrupt */
 114 static volatile unsigned char reply_expected = 0;
 115 static volatile unsigned char acknowledge = 0;
 116 static volatile unsigned char resend = 0;
 117 
 118 extern void compute_shiftstate(void);
 119 
 120 typedef void (*k_hand)(unsigned char value, char up_flag);
 121 typedef void (k_handfn)(unsigned char value, char up_flag);
 122 
 123 static k_handfn
 124         do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
 125         do_meta, do_ascii, do_lock, do_lowercase, do_ignore;
 126 
 127 static k_hand key_handler[16] = {
 128         do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
 129         do_meta, do_ascii, do_lock, do_lowercase,
 130         do_ignore, do_ignore, do_ignore, do_ignore
 131 };
 132 
 133 typedef void (*void_fnp)(void);
 134 typedef void (void_fn)(void);
 135 
 136 static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle,
 137         num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose,
 138         SAK, decr_console, incr_console, spawn_console;
 139 
 140 static void_fnp spec_fn_table[] = {
 141         do_null,        enter,          show_ptregs,    show_mem,
 142         show_state,     send_intr,      lastcons,       caps_toggle,
 143         num,            hold,           scroll_forw,    scroll_back,
 144         boot_it,        caps_on,        compose,        SAK,
 145         decr_console,   incr_console,   spawn_console
 146 };
 147 
 148 /* maximum values each key_handler can handle */
 149 const int max_vals[] = {
 150         255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
 151         NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
 152         255, NR_ASCII - 1, NR_LOCK - 1, 255
 153 };
 154 
 155 const int NR_TYPES = SIZE(max_vals);
 156 
 157 static void put_queue(int);
 158 static unsigned char handle_diacr(unsigned char);
 159 
 160 /* pt_regs - set by keyboard_interrupt(), used by show_ptregs() */
 161 static struct pt_regs * pt_regs;
 162 
 163 static inline void kb_wait(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 164 {
 165         int i;
 166 
 167         for (i=0; i<0x100000; i++)
 168                 if ((inb_p(0x64) & 0x02) == 0)
 169                         return;
 170         printk("Keyboard timed out\n");
 171 }
 172 
 173 static inline void send_cmd(unsigned char c)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175         kb_wait();
 176         outb(c,0x64);
 177 }
 178 
 179 /*
 180  * Many other routines do put_queue, but I think either
 181  * they produce ASCII, or they produce some user-assigned
 182  * string, and in both cases we might assume that it is
 183  * in utf-8 already.
 184  */
 185 void to_utf8(ushort c) {
     /* [previous][next][first][last][top][bottom][index][help] */
 186     if (c < 0x80)
 187         put_queue(c);                   /*  0*******  */
 188     else if (c < 0x800) {
 189         put_queue(0xc0 | (c >> 6));     /*  110***** 10******  */
 190         put_queue(0x80 | (c & 0x3f));
 191     } else {
 192         put_queue(0xe0 | (c >> 12));    /*  1110**** 10****** 10******  */
 193         put_queue(0x80 | ((c >> 6) & 0x3f));
 194         put_queue(0x80 | (c & 0x3f));
 195     }
 196     /* UTF-8 is defined for words of up to 31 bits,
 197        but we need only 16 bits here */
 198 }
 199 
 200 /*
 201  * Translation of escaped scancodes to keycodes.
 202  * This is now user-settable.
 203  * The keycodes 1-88,96-111,119 are fairly standard, and
 204  * should probably not be changed - changing might confuse X.
 205  * X also interprets scancode 0x5d (KEY_Begin).
 206  *
 207  * For 1-88 keycode equals scancode.
 208  */
 209 
 210 #define E0_KPENTER 96
 211 #define E0_RCTRL   97
 212 #define E0_KPSLASH 98
 213 #define E0_PRSCR   99
 214 #define E0_RALT    100
 215 #define E0_BREAK   101  /* (control-pause) */
 216 #define E0_HOME    102
 217 #define E0_UP      103
 218 #define E0_PGUP    104
 219 #define E0_LEFT    105
 220 #define E0_RIGHT   106
 221 #define E0_END     107
 222 #define E0_DOWN    108
 223 #define E0_PGDN    109
 224 #define E0_INS     110
 225 #define E0_DEL     111
 226 
 227 #define E1_PAUSE   119
 228 
 229 /*
 230  * The keycodes below are randomly located in 89-95,112-118,120-127.
 231  * They could be thrown away (and all occurrences below replaced by 0),
 232  * but that would force many users to use the `setkeycodes' utility, where
 233  * they needed not before. It does not matter that there are duplicates, as
 234  * long as no duplication occurs for any single keyboard.
 235  */
 236 #define SC_LIM 89
 237 
 238 #define FOCUS_PF1 85           /* actual code! */
 239 #define FOCUS_PF2 89
 240 #define FOCUS_PF3 90
 241 #define FOCUS_PF4 91
 242 #define FOCUS_PF5 92
 243 #define FOCUS_PF6 93
 244 #define FOCUS_PF7 94
 245 #define FOCUS_PF8 95
 246 #define FOCUS_PF9 120
 247 #define FOCUS_PF10 121
 248 #define FOCUS_PF11 122
 249 #define FOCUS_PF12 123
 250 
 251 #define JAP_86     124
 252 /* tfj@olivia.ping.dk:
 253  * The four keys are located over the numeric keypad, and are
 254  * labelled A1-A4. It's an rc930 keyboard, from
 255  * Regnecentralen/RC International, Now ICL.
 256  * Scancodes: 59, 5a, 5b, 5c.
 257  */
 258 #define RGN1 124
 259 #define RGN2 125
 260 #define RGN3 126
 261 #define RGN4 127
 262 
 263 static unsigned char high_keys[128 - SC_LIM] = {
 264   RGN1, RGN2, RGN3, RGN4, 0, 0, 0,                   /* 0x59-0x5f */
 265   0, 0, 0, 0, 0, 0, 0, 0,                            /* 0x60-0x67 */
 266   0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,          /* 0x68-0x6f */
 267   0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,    /* 0x70-0x77 */
 268   FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,        /* 0x78-0x7b */
 269   FOCUS_PF8, JAP_86, FOCUS_PF10, 0                   /* 0x7c-0x7f */
 270 };
 271 
 272 /* BTC */
 273 #define E0_MACRO   112
 274 /* LK450 */
 275 #define E0_F13     113
 276 #define E0_F14     114
 277 #define E0_HELP    115
 278 #define E0_DO      116
 279 #define E0_F17     117
 280 #define E0_KPMINPLUS 118
 281 /*
 282  * My OmniKey generates e0 4c for  the "OMNI" key and the
 283  * right alt key does nada. [kkoller@nyx10.cs.du.edu]
 284  */
 285 #define E0_OK   124
 286 /*
 287  * New microsoft keyboard is rumoured to have
 288  * e0 5b (left window button), e0 5c (right window button),
 289  * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
 290  * [or: Windows_L, Windows_R, TaskMan]
 291  */
 292 #define E0_MSLW 125
 293 #define E0_MSRW 126
 294 #define E0_MSTM 127
 295 
 296 static unsigned char e0_keys[128] = {
 297   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x00-0x07 */
 298   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x08-0x0f */
 299   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x10-0x17 */
 300   0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,             /* 0x18-0x1f */
 301   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x20-0x27 */
 302   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x28-0x2f */
 303   0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,             /* 0x30-0x37 */
 304   E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,       /* 0x38-0x3f */
 305   E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,       /* 0x40-0x47 */
 306   E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
 307   E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,       /* 0x50-0x57 */
 308   0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,           /* 0x58-0x5f */
 309   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x60-0x67 */
 310   0, 0, 0, 0, 0, 0, 0, E0_MACRO,                      /* 0x68-0x6f */
 311   0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x70-0x77 */
 312   0, 0, 0, 0, 0, 0, 0, 0                              /* 0x78-0x7f */
 313 };
 314 
 315 int setkeycode(unsigned int scancode, unsigned int keycode)
     /* [previous][next][first][last][top][bottom][index][help] */
 316 {
 317         if (scancode < SC_LIM || scancode > 255 || keycode > 127)
 318           return -EINVAL;
 319         if (scancode < 128)
 320           high_keys[scancode - SC_LIM] = keycode;
 321         else
 322           e0_keys[scancode - 128] = keycode;
 323         return 0;
 324 }
 325 
 326 int getkeycode(unsigned int scancode)
     /* [previous][next][first][last][top][bottom][index][help] */
 327 {
 328         return
 329           (scancode < SC_LIM || scancode > 255) ? -EINVAL :
 330           (scancode < 128) ? high_keys[scancode - SC_LIM] :
 331             e0_keys[scancode - 128];
 332 }
 333 
 334 static void keyboard_interrupt(int irq, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 335 {
 336         unsigned char scancode, keycode;
 337         static unsigned int prev_scancode = 0;   /* remember E0, E1 */
 338         char up_flag;                            /* 0 or 0200 */
 339         char raw_mode;
 340 
 341         pt_regs = regs;
 342         send_cmd(0xAD);         /* disable keyboard */
 343         kb_wait();
 344         if ((inb_p(0x64) & kbd_read_mask) != 0x01)
 345                 goto end_kbd_intr;
 346         scancode = inb(0x60);
 347         mark_bh(KEYBOARD_BH);
 348         if (reply_expected) {
 349           /* 0xfa, 0xfe only mean "acknowledge", "resend" for most keyboards */
 350           /* but they are the key-up scancodes for PF6, PF10 on a FOCUS 9000 */
 351                 reply_expected = 0;
 352                 if (scancode == 0xfa) {
 353                         acknowledge = 1;
 354                         goto end_kbd_intr;
 355                 } else if (scancode == 0xfe) {
 356                         resend = 1;
 357                         goto end_kbd_intr;
 358                 }
 359                 /* strange ... */
 360                 reply_expected = 1;
 361 #if 0
 362                 printk("keyboard reply expected - got %02x\n", scancode);
 363 #endif
 364         }
 365         if (scancode == 0) {
 366 #ifdef KBD_REPORT_ERR
 367                 printk("keyboard buffer overflow\n");
 368 #endif
 369                 prev_scancode = 0;
 370                 goto end_kbd_intr;
 371         }
 372         if (scancode == 0xff) {
 373                 /* the calculator keys on a FOCUS 9000 generate 0xff */
 374 #ifndef KBD_IS_FOCUS_9000
 375 #ifdef KBD_REPORT_ERR
 376                 printk("keyboard error\n");
 377 #endif
 378 #endif
 379                 prev_scancode = 0;
 380                 goto end_kbd_intr;
 381         }
 382 
 383         tty = ttytab[fg_console];
 384         kbd = kbd_table + fg_console;
 385         if ((raw_mode = (kbd->kbdmode == VC_RAW))) {
 386                 put_queue(scancode);
 387                 /* we do not return yet, because we want to maintain
 388                    the key_down array, so that we have the correct
 389                    values when finishing RAW mode or when changing VT's */
 390         }
 391         if (scancode == 0xe0 || scancode == 0xe1) {
 392                 prev_scancode = scancode;
 393                 goto end_kbd_intr;
 394         }
 395 
 396         /*
 397          *  Convert scancode to keycode, using prev_scancode.
 398          */
 399         up_flag = (scancode & 0200);
 400         scancode &= 0x7f;
 401 
 402         if (prev_scancode) {
 403           /*
 404            * usually it will be 0xe0, but a Pause key generates
 405            * e1 1d 45 e1 9d c5 when pressed, and nothing when released
 406            */
 407           if (prev_scancode != 0xe0) {
 408               if (prev_scancode == 0xe1 && scancode == 0x1d) {
 409                   prev_scancode = 0x100;
 410                   goto end_kbd_intr;
 411               } else if (prev_scancode == 0x100 && scancode == 0x45) {
 412                   keycode = E1_PAUSE;
 413                   prev_scancode = 0;
 414               } else {
 415 #ifdef KBD_REPORT_UNKN
 416                   printk("keyboard: unknown e1 escape sequence\n");
 417 #endif
 418                   prev_scancode = 0;
 419                   goto end_kbd_intr;
 420               }
 421           } else {
 422               prev_scancode = 0;
 423               /*
 424                *  The keyboard maintains its own internal caps lock and
 425                *  num lock statuses. In caps lock mode E0 AA precedes make
 426                *  code and E0 2A follows break code. In num lock mode,
 427                *  E0 2A precedes make code and E0 AA follows break code.
 428                *  We do our own book-keeping, so we will just ignore these.
 429                */
 430               /*
 431                *  For my keyboard there is no caps lock mode, but there are
 432                *  both Shift-L and Shift-R modes. The former mode generates
 433                *  E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
 434                *  So, we should also ignore the latter. - aeb@cwi.nl
 435                */
 436               if (scancode == 0x2a || scancode == 0x36)
 437                 goto end_kbd_intr;
 438 
 439               if (e0_keys[scancode])
 440                 keycode = e0_keys[scancode];
 441               else {
 442 #ifdef KBD_REPORT_UNKN
 443                   if (!raw_mode)
 444                     printk("keyboard: unknown scancode e0 %02x\n", scancode);
 445 #endif
 446                   goto end_kbd_intr;
 447               }
 448           }
 449         } else if (scancode >= SC_LIM) {
 450             /* This happens with the FOCUS 9000 keyboard
 451                Its keys PF1..PF12 are reported to generate
 452                55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
 453                Moreover, unless repeated, they do not generate
 454                key-down events, so we have to zero up_flag below */
 455             /* Also, Japanese 86/106 keyboards are reported to
 456                generate 0x73 and 0x7d for \ - and \ | respectively. */
 457             /* Also, some Brazilian keyboard is reported to produce
 458                0x73 and 0x7e for \ ? and KP-dot, respectively. */
 459 
 460           keycode = high_keys[scancode - SC_LIM];
 461 
 462           if (!keycode) {
 463               if (!raw_mode) {
 464 #ifdef KBD_REPORT_UNKN
 465                   printk("keyboard: unrecognized scancode (%02x) - ignored\n"
 466                          , scancode);
 467 #endif
 468               }
 469               goto end_kbd_intr;
 470           }
 471         } else
 472           keycode = scancode;
 473 
 474         /*
 475          * At this point the variable `keycode' contains the keycode.
 476          * Note: the keycode must not be 0.
 477          * We keep track of the up/down status of the key, and
 478          * return the keycode if in MEDIUMRAW mode.
 479          */
 480 
 481         if (up_flag) {
 482                 rep = 0;
 483                 if(!clear_bit(keycode, key_down)) {
 484                     /* unexpected, but this can happen:
 485                        maybe this was a key release for a FOCUS 9000
 486                        PF key; if we want to see it, we have to clear
 487                        up_flag */
 488                     if (keycode >= SC_LIM || keycode == 85)
 489                       up_flag = 0;
 490                 }
 491         } else
 492                 rep = set_bit(keycode, key_down);
 493 
 494         if (raw_mode)
 495                 goto end_kbd_intr;
 496 
 497         if (kbd->kbdmode == VC_MEDIUMRAW) {
 498                 /* soon keycodes will require more than one byte */
 499                 put_queue(keycode + up_flag);
 500                 goto end_kbd_intr;
 501         }
 502 
 503         /*
 504          * Small change in philosophy: earlier we defined repetition by
 505          *       rep = keycode == prev_keycode;
 506          *       prev_keycode = keycode;
 507          * but now by the fact that the depressed key was down already.
 508          * Does this ever make a difference? Yes.
 509          */
 510 
 511         /*
 512          *  Repeat a key only if the input buffers are empty or the
 513          *  characters get echoed locally. This makes key repeat usable
 514          *  with slow applications and under heavy loads.
 515          */
 516         if (!rep ||
 517             (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
 518              (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
 519                 u_short keysym;
 520                 u_char type;
 521 
 522                 /* the XOR below used to be an OR */
 523                 int shift_final = shift_state ^ kbd->lockstate;
 524                 ushort *key_map = key_maps[shift_final];
 525 
 526                 if (key_map != NULL) {
 527                         keysym = key_map[keycode];
 528                         type = KTYP(keysym);
 529 
 530                         if (type >= 0xf0) {
 531                             type -= 0xf0;
 532                             if (type == KT_LETTER) {
 533                                 type = KT_LATIN;
 534                                 if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
 535                                     key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
 536                                     if (key_map)
 537                                       keysym = key_map[keycode];
 538                                 }
 539                             }
 540                             (*key_handler[type])(keysym & 0xff, up_flag);
 541                         } else {
 542                             /* maybe only if (kbd->kbdmode == VC_UNICODE) ? */
 543                             if (!up_flag)
 544                               to_utf8(keysym);
 545                         }
 546                 } else {
 547                         /* maybe beep? */
 548                         /* we have at least to update shift_state */
 549 #if 1                   /* how? two almost equivalent choices follow */
 550                         compute_shiftstate();
 551 #else
 552                         keysym = U(plain_map[keycode]);
 553                         type = KTYP(keysym);
 554                         if (type == KT_SHIFT)
 555                           (*key_handler[type])(keysym & 0xff, up_flag);
 556 #endif
 557                 }
 558         }
 559 
 560 end_kbd_intr:
 561         send_cmd(0xAE);         /* enable keyboard */
 562 }
 563 
 564 static void put_queue(int ch)
     /* [previous][next][first][last][top][bottom][index][help] */
 565 {
 566         wake_up(&keypress_wait);
 567         if (tty) {
 568                 tty_insert_flip_char(tty, ch, 0);
 569                 tty_schedule_flip(tty);
 570         }
 571 }
 572 
 573 static void puts_queue(char *cp)
     /* [previous][next][first][last][top][bottom][index][help] */
 574 {
 575         wake_up(&keypress_wait);
 576         if (!tty)
 577                 return;
 578 
 579         while (*cp) {
 580                 tty_insert_flip_char(tty, *cp, 0);
 581                 cp++;
 582         }
 583         tty_schedule_flip(tty);
 584 }
 585 
 586 static void applkey(int key, char mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 587 {
 588         static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
 589 
 590         buf[1] = (mode ? 'O' : '[');
 591         buf[2] = key;
 592         puts_queue(buf);
 593 }
 594 
 595 static void enter(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 596 {
 597         put_queue(13);
 598         if (vc_kbd_mode(kbd,VC_CRLF))
 599                 put_queue(10);
 600 }
 601 
 602 static void caps_toggle(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 603 {
 604         if (rep)
 605                 return;
 606         chg_vc_kbd_led(kbd, VC_CAPSLOCK);
 607 }
 608 
 609 static void caps_on(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 610 {
 611         if (rep)
 612                 return;
 613         set_vc_kbd_led(kbd, VC_CAPSLOCK);
 614 }
 615 
 616 static void show_ptregs(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 617 {
 618         if (pt_regs)
 619                 show_regs(pt_regs);
 620 }
 621 
 622 static void hold(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 623 {
 624         if (rep || !tty)
 625                 return;
 626 
 627         /*
 628          * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
 629          * these routines are also activated by ^S/^Q.
 630          * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
 631          */
 632         if (tty->stopped)
 633                 start_tty(tty);
 634         else
 635                 stop_tty(tty);
 636 }
 637 
 638 static void num(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 639 {
 640         if (vc_kbd_mode(kbd,VC_APPLIC)) {
 641                 applkey('P', 1);
 642                 return;
 643         }
 644         if (!rep)       /* no autorepeat for numlock, ChN */
 645                 chg_vc_kbd_led(kbd,VC_NUMLOCK);
 646 }
 647 
 648 static void lastcons(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 649 {
 650         /* switch to the last used console, ChN */
 651         want_console = last_console;
 652 }
 653 
 654 static void decr_console(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 655 {
 656         int i;
 657  
 658         for (i = fg_console-1; i != fg_console; i--) {
 659                 if (i == -1)
 660                         i = MAX_NR_CONSOLES-1;
 661                 if (vc_cons_allocated(i))
 662                         break;
 663         }
 664         want_console = i;
 665 }
 666 
 667 static void incr_console(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 668 {
 669         int i;
 670 
 671         for (i = fg_console+1; i != fg_console; i++) {
 672                 if (i == MAX_NR_CONSOLES)
 673                         i = 0;
 674                 if (vc_cons_allocated(i))
 675                         break;
 676         }
 677         want_console = i;
 678 }
 679 
 680 static void send_intr(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 681 {
 682         if (!tty)
 683                 return;
 684         tty_insert_flip_char(tty, 0, TTY_BREAK);
 685         tty_schedule_flip(tty);
 686 }
 687 
 688 static void scroll_forw(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 689 {
 690         scrollfront(0);
 691 }
 692 
 693 static void scroll_back(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 694 {
 695         scrollback(0);
 696 }
 697 
 698 static void boot_it(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 699 {
 700         ctrl_alt_del();
 701 }
 702 
 703 static void compose(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 704 {
 705         dead_key_next = 1;
 706 }
 707 
 708 int spawnpid, spawnsig;
 709 
 710 static void spawn_console(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 711 {
 712         if (spawnpid)
 713            if(kill_proc(spawnpid, spawnsig, 1))
 714              spawnpid = 0;
 715 }
 716 
 717 static void SAK(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 718 {
 719         do_SAK(tty);
 720 #if 0
 721         /*
 722          * Need to fix SAK handling to fix up RAW/MEDIUM_RAW and
 723          * vt_cons modes before we can enable RAW/MEDIUM_RAW SAK
 724          * handling.
 725          * 
 726          * We should do this some day --- the whole point of a secure
 727          * attention key is that it should be guaranteed to always
 728          * work.
 729          */
 730         reset_vc(fg_console);
 731         unblank_screen();       /* not in interrupt routine? */
 732 #endif
 733 }
 734 
 735 static void do_ignore(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 736 {
 737 }
 738 
 739 static void do_null()
     /* [previous][next][first][last][top][bottom][index][help] */
 740 {
 741         compute_shiftstate();
 742 }
 743 
 744 static void do_spec(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 745 {
 746         if (up_flag)
 747                 return;
 748         if (value >= SIZE(spec_fn_table))
 749                 return;
 750         spec_fn_table[value]();
 751 }
 752 
 753 static void do_lowercase(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 754 {
 755         printk("keyboard.c: do_lowercase was called - impossible\n");
 756 }
 757 
 758 static void do_self(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 759 {
 760         if (up_flag)
 761                 return;         /* no action, if this is a key release */
 762 
 763         if (diacr)
 764                 value = handle_diacr(value);
 765 
 766         if (dead_key_next) {
 767                 dead_key_next = 0;
 768                 diacr = value;
 769                 return;
 770         }
 771 
 772         put_queue(value);
 773 }
 774 
 775 #define A_GRAVE  '`'
 776 #define A_ACUTE  '\''
 777 #define A_CFLEX  '^'
 778 #define A_TILDE  '~'
 779 #define A_DIAER  '"'
 780 static unsigned char ret_diacr[] =
 781         {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER };
 782 
 783 /* If a dead key pressed twice, output a character corresponding to it, */
 784 /* otherwise just remember the dead key.                                */
 785 
 786 static void do_dead(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 787 {
 788         if (up_flag)
 789                 return;
 790 
 791         value = ret_diacr[value];
 792         if (diacr == value) {   /* pressed twice */
 793                 diacr = 0;
 794                 put_queue(value);
 795                 return;
 796         }
 797         diacr = value;
 798 }
 799 
 800 
 801 /* If space is pressed, return the character corresponding the pending  */
 802 /* dead key, otherwise try to combine the two.                          */
 803 
 804 unsigned char handle_diacr(unsigned char ch)
     /* [previous][next][first][last][top][bottom][index][help] */
 805 {
 806         int d = diacr;
 807         int i;
 808 
 809         diacr = 0;
 810         if (ch == ' ')
 811                 return d;
 812 
 813         for (i = 0; i < accent_table_size; i++) {
 814                 if (accent_table[i].diacr == d && accent_table[i].base == ch)
 815                         return accent_table[i].result;
 816         }
 817 
 818         put_queue(d);
 819         return ch;
 820 }
 821 
 822 static void do_cons(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 823 {
 824         if (up_flag)
 825                 return;
 826         want_console = value;
 827 }
 828 
 829 static void do_fn(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 830 {
 831         if (up_flag)
 832                 return;
 833         if (value < SIZE(func_table)) {
 834                 if (func_table[value])
 835                         puts_queue(func_table[value]);
 836         } else
 837                 printk("do_fn called with value=%d\n", value);
 838 }
 839 
 840 static void do_pad(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 841 {
 842         static char *pad_chars = "0123456789+-*/\015,.?";
 843         static char *app_map = "pqrstuvwxylSRQMnn?";
 844 
 845         if (up_flag)
 846                 return;         /* no action, if this is a key release */
 847 
 848         /* kludge... shift forces cursor/number keys */
 849         if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
 850                 applkey(app_map[value], 1);
 851                 return;
 852         }
 853 
 854         if (!vc_kbd_led(kbd,VC_NUMLOCK))
 855                 switch (value) {
 856                         case KVAL(K_PCOMMA):
 857                         case KVAL(K_PDOT):
 858                                 do_fn(KVAL(K_REMOVE), 0);
 859                                 return;
 860                         case KVAL(K_P0):
 861                                 do_fn(KVAL(K_INSERT), 0);
 862                                 return;
 863                         case KVAL(K_P1):
 864                                 do_fn(KVAL(K_SELECT), 0);
 865                                 return;
 866                         case KVAL(K_P2):
 867                                 do_cur(KVAL(K_DOWN), 0);
 868                                 return;
 869                         case KVAL(K_P3):
 870                                 do_fn(KVAL(K_PGDN), 0);
 871                                 return;
 872                         case KVAL(K_P4):
 873                                 do_cur(KVAL(K_LEFT), 0);
 874                                 return;
 875                         case KVAL(K_P6):
 876                                 do_cur(KVAL(K_RIGHT), 0);
 877                                 return;
 878                         case KVAL(K_P7):
 879                                 do_fn(KVAL(K_FIND), 0);
 880                                 return;
 881                         case KVAL(K_P8):
 882                                 do_cur(KVAL(K_UP), 0);
 883                                 return;
 884                         case KVAL(K_P9):
 885                                 do_fn(KVAL(K_PGUP), 0);
 886                                 return;
 887                         case KVAL(K_P5):
 888                                 applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
 889                                 return;
 890                 }
 891 
 892         put_queue(pad_chars[value]);
 893         if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
 894                 put_queue(10);
 895 }
 896 
 897 static void do_cur(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 898 {
 899         static char *cur_chars = "BDCA";
 900         if (up_flag)
 901                 return;
 902 
 903         applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
 904 }
 905 
 906 static void do_shift(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 907 {
 908         int old_state = shift_state;
 909 
 910         if (rep)
 911                 return;
 912 
 913         /* Mimic typewriter:
 914            a CapsShift key acts like Shift but undoes CapsLock */
 915         if (value == KVAL(K_CAPSSHIFT)) {
 916                 value = KVAL(K_SHIFT);
 917                 if (!up_flag)
 918                         clr_vc_kbd_led(kbd, VC_CAPSLOCK);
 919         }
 920 
 921         if (up_flag) {
 922                 /* handle the case that two shift or control
 923                    keys are depressed simultaneously */
 924                 if (k_down[value])
 925                         k_down[value]--;
 926         } else
 927                 k_down[value]++;
 928 
 929         if (k_down[value])
 930                 shift_state |= (1 << value);
 931         else
 932                 shift_state &= ~ (1 << value);
 933 
 934         /* kludge */
 935         if (up_flag && shift_state != old_state && npadch != -1) {
 936                 if (kbd->kbdmode == VC_UNICODE)
 937                   to_utf8(npadch & 0xffff);
 938                 else
 939                   put_queue(npadch & 0xff);
 940                 npadch = -1;
 941         }
 942 }
 943 
 944 /* called after returning from RAW mode or when changing consoles -
 945    recompute k_down[] and shift_state from key_down[] */
 946 /* maybe called when keymap is undefined, so that shiftkey release is seen */
 947 void compute_shiftstate(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 948 {
 949         int i, j, k, sym, val;
 950 
 951         shift_state = 0;
 952         for(i=0; i < SIZE(k_down); i++)
 953           k_down[i] = 0;
 954 
 955         for(i=0; i < SIZE(key_down); i++)
 956           if(key_down[i]) {     /* skip this word if not a single bit on */
 957             k = (i<<5);
 958             for(j=0; j<32; j++,k++)
 959               if(test_bit(k, key_down)) {
 960                 sym = U(plain_map[k]);
 961                 if(KTYP(sym) == KT_SHIFT) {
 962                   val = KVAL(sym);
 963                   if (val == KVAL(K_CAPSSHIFT))
 964                     val = KVAL(K_SHIFT);
 965                   k_down[val]++;
 966                   shift_state |= (1<<val);
 967                 }
 968               }
 969           }
 970 }
 971 
 972 static void do_meta(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 973 {
 974         if (up_flag)
 975                 return;
 976 
 977         if (vc_kbd_mode(kbd, VC_META)) {
 978                 put_queue('\033');
 979                 put_queue(value);
 980         } else
 981                 put_queue(value | 0x80);
 982 }
 983 
 984 static void do_ascii(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 985 {
 986         int base;
 987 
 988         if (up_flag)
 989                 return;
 990 
 991         if (value < 10)    /* decimal input of code, while Alt depressed */
 992             base = 10;
 993         else {       /* hexadecimal input of code, while AltGr depressed */
 994             value -= 10;
 995             base = 16;
 996         }
 997 
 998         if (npadch == -1)
 999           npadch = value;
1000         else
1001           npadch = npadch * base + value;
1002 }
1003 
1004 static void do_lock(unsigned char value, char up_flag)
     /* [previous][next][first][last][top][bottom][index][help] */
1005 {
1006         if (up_flag || rep)
1007                 return;
1008         chg_vc_kbd_lock(kbd, value);
1009 }
1010 
1011 /*
1012  * send_data sends a character to the keyboard and waits
1013  * for a acknowledge, possibly retrying if asked to. Returns
1014  * the success status.
1015  */
1016 static int send_data(unsigned char data)
     /* [previous][next][first][last][top][bottom][index][help] */
1017 {
1018         int retries = 3;
1019         int i;
1020 
1021         do {
1022                 kb_wait();
1023                 acknowledge = 0;
1024                 resend = 0;
1025                 reply_expected = 1;
1026                 outb_p(data, 0x60);
1027                 for(i=0; i<0x200000; i++) {
1028                         inb_p(0x64);            /* just as a delay */
1029                         if (acknowledge)
1030                                 return 1;
1031                         if (resend)
1032                                 break;
1033                 }
1034                 if (!resend)
1035                         return 0;
1036         } while (retries-- > 0);
1037         return 0;
1038 }
1039 
1040 /*
1041  * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
1042  * or (ii) whatever pattern of lights people want to show using KDSETLED,
1043  * or (iii) specified bits of specified words in kernel memory.
1044  */
1045 
1046 static unsigned char ledstate = 0xff; /* undefined */
1047 static unsigned char ledioctl;
1048 
1049 unsigned char getledstate(void) {
     /* [previous][next][first][last][top][bottom][index][help] */
1050     return ledstate;
1051 }
1052 
1053 void setledstate(struct kbd_struct *kbd, unsigned int led) {
     /* [previous][next][first][last][top][bottom][index][help] */
1054     if (!(led & ~7)) {
1055         ledioctl = led;
1056         kbd->ledmode = LED_SHOW_IOCTL;
1057     } else
1058         kbd->ledmode = LED_SHOW_FLAGS;
1059     set_leds();
1060 }
1061 
1062 static struct ledptr {
1063     unsigned int *addr;
1064     unsigned int mask;
1065     unsigned char valid:1;
1066 } ledptrs[3];
1067 
1068 void register_leds(int console, unsigned int led,
     /* [previous][next][first][last][top][bottom][index][help] */
1069                    unsigned int *addr, unsigned int mask) {
1070     struct kbd_struct *kbd = kbd_table + console;
1071     if (led < 3) {
1072         ledptrs[led].addr = addr;
1073         ledptrs[led].mask = mask;
1074         ledptrs[led].valid = 1;
1075         kbd->ledmode = LED_SHOW_MEM;
1076     } else
1077         kbd->ledmode = LED_SHOW_FLAGS;
1078 }
1079 
1080 static inline unsigned char getleds(void){
     /* [previous][next][first][last][top][bottom][index][help] */
1081     struct kbd_struct *kbd = kbd_table + fg_console;
1082     unsigned char leds;
1083 
1084     if (kbd->ledmode == LED_SHOW_IOCTL)
1085       return ledioctl;
1086     leds = kbd->ledflagstate;
1087     if (kbd->ledmode == LED_SHOW_MEM) {
1088         if (ledptrs[0].valid) {
1089             if (*ledptrs[0].addr & ledptrs[0].mask)
1090               leds |= 1;
1091             else
1092               leds &= ~1;
1093         }
1094         if (ledptrs[1].valid) {
1095             if (*ledptrs[1].addr & ledptrs[1].mask)
1096               leds |= 2;
1097             else
1098               leds &= ~2;
1099         }
1100         if (ledptrs[2].valid) {
1101             if (*ledptrs[2].addr & ledptrs[2].mask)
1102               leds |= 4;
1103             else
1104               leds &= ~4;
1105         }
1106     }
1107     return leds;
1108 }
1109 
1110 /*
1111  * This routine is the bottom half of the keyboard interrupt
1112  * routine, and runs with all interrupts enabled. It does
1113  * console changing, led setting and copy_to_cooked, which can
1114  * take a reasonably long time.
1115  *
1116  * Aside from timing (which isn't really that important for
1117  * keyboard interrupts as they happen often), using the software
1118  * interrupt routines for this thing allows us to easily mask
1119  * this when we don't want any of the above to happen. Not yet
1120  * used, but this allows for easy and efficient race-condition
1121  * prevention later on.
1122  */
1123 static void kbd_bh(void * unused)
     /* [previous][next][first][last][top][bottom][index][help] */
1124 {
1125         unsigned char leds = getleds();
1126 
1127         if (leds != ledstate) {
1128                 ledstate = leds;
1129                 if (!send_data(0xed) || !send_data(leds))
1130                         send_data(0xf4);        /* re-enable kbd if any errors */
1131         }
1132         if (want_console >= 0) {
1133                 if (want_console != fg_console) {
1134                         change_console(want_console);
1135                         /* we only changed when the console had already
1136                            been allocated - a new console is not created
1137                            in an interrupt routine */
1138                 }
1139                 want_console = -1;
1140         }
1141         poke_blanked_console();
1142         cli();
1143         if ((inb_p(0x64) & kbd_read_mask) == 0x01)
1144                 fake_keyboard_interrupt();
1145         sti();
1146 }
1147 
1148 unsigned long kbd_init(unsigned long kmem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
1149 {
1150         int i;
1151         struct kbd_struct kbd0;
1152         extern struct tty_driver console_driver;
1153 
1154         kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
1155         kbd0.ledmode = LED_SHOW_FLAGS;
1156         kbd0.lockstate = KBD_DEFLOCK;
1157         kbd0.modeflags = KBD_DEFMODE;
1158         kbd0.kbdmode = VC_XLATE;
1159  
1160         for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
1161                 kbd_table[i] = kbd0;
1162 
1163         ttytab = console_driver.table;
1164 
1165         bh_base[KEYBOARD_BH].routine = kbd_bh;
1166         request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard");
1167 #ifdef __alpha__
1168         /* enable keyboard interrupts, PC/AT mode */
1169         kb_wait();
1170         outb(0x60,0x64);        /* write PS/2 Mode Register */
1171         kb_wait();
1172         outb(0x41,0x60);        /* KCC | EKI */
1173         kb_wait();
1174         if (!send_data(0xf0) || !send_data(0x02))
1175                 printk("Scanmode 2 change failed\n");
1176 #endif
1177         mark_bh(KEYBOARD_BH);
1178         enable_bh(KEYBOARD_BH);
1179         return kmem_start;
1180 }

/* [previous][next][first][last][top][bottom][index][help] */