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

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