root/drivers/char/keyboard.c

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

DEFINITIONS

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

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