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

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