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

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