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

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