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

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