root/drivers/char/keyboard.c

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

DEFINITIONS

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

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