root/drivers/char/keyboard.c

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

DEFINITIONS

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

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

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