home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / drivers / char / keyboard.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-09  |  21.9 KB  |  971 lines

  1. /*
  2.  * linux/kernel/chr_drv/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.  * Loadable keymaps by Risto Kankkunen, May 1993
  11.  * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
  12.  */
  13.  
  14. /*
  15.  * general 680x0 support by Hamish Macdonald
  16.  */
  17.  
  18. #include <linux/sched.h>
  19. #include <linux/tty.h>
  20. #include <linux/mm.h>
  21. #include <linux/ptrace.h>
  22. #include <linux/interrupt.h>
  23. #include <linux/config.h>
  24. #include <linux/signal.h>
  25. #include <linux/string.h>
  26.  
  27. #include <asm/bitops.h>
  28.  
  29. #include "kbd_kern.h"
  30. #include "diacr.h"
  31.  
  32. /* to comment out PC specific stuff */
  33. #undef __pc_stuff__
  34. #undef notyet
  35.  
  36. #define SIZE(x) (sizeof(x)/sizeof((x)[0]))
  37.  
  38. #define KBD_REPORT_ERR
  39. #define KBD_REPORT_UNKN
  40.  
  41. #ifndef KBD_DEFMODE
  42. #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
  43. #endif
  44.  
  45. #ifndef KBD_DEFLEDS
  46. /*
  47.  * Some laptops take the 789uiojklm,. keys as number pad when NumLock
  48.  * is on. This seems a good reason to start with NumLock off.
  49.  */
  50. /* Can the above happen for Linux/68k? I think no, so enable NumLock by
  51.  * default!
  52.  */
  53. #ifndef __pc_stuff__
  54. #define KBD_DEFLEDS (1 << VC_NUMLOCK)
  55. #else
  56. #define KBD_DEFLEDS 0
  57. #endif
  58.  
  59. #endif
  60.  
  61. #ifndef KBD_DEFLOCK
  62. #define KBD_DEFLOCK 0
  63. #endif
  64.  
  65. #ifdef __pc_stuf__
  66. /*
  67.  * The default IO slowdown is doing 'inb()'s from 0x61, which should be
  68.  * safe. But as that is the keyboard controller chip address, we do our
  69.  * slowdowns here by doing short jumps: the keyboard controller should
  70.  * be able to keep up
  71.  */
  72. #define REALLY_SLOW_IO
  73. #define SLOW_IO_BY_JUMPING
  74. #include <asm/io.h>
  75. #include <asm/system.h>
  76.  
  77. #endif
  78.  
  79. extern void do_keyboard_interrupt(void);
  80. extern void ctrl_alt_del(void);
  81. extern void change_console(unsigned int new_console);
  82. extern void scrollback(int);
  83. extern void scrollfront(int);
  84.  
  85. #ifdef __pc_stuff__
  86.  
  87. #define fake_keyboard_interrupt() \
  88. __asm__ __volatile__("int $0x21")
  89.  
  90. #endif
  91.  
  92. unsigned char kbd_read_mask = 0x01;    /* modified by psaux.c */
  93.  
  94. /*
  95.  * global state includes the following, and various static variables
  96.  * in this module: prev_scancode, shift_state, diacr, npadch,
  97.  *   dead_key_next, last_console
  98.  */
  99.  
  100. /* shift state counters.. */
  101. static unsigned char k_down[NR_SHIFT] = {0, };
  102. /* keyboard key bitmap */
  103. static unsigned long key_down[8] = { 0, };
  104.  
  105. static int want_console = -1;
  106. static int last_console = 0;        /* last used VC */
  107. static int dead_key_next = 0;
  108. static int shift_state = 0;
  109. static int npadch = -1;                /* -1 or number assembled on pad */
  110. static unsigned char diacr = 0;
  111. static char rep = 0;            /* flag telling character repeat */
  112. struct kbd_struct kbd_table[NR_CONSOLES];
  113. static struct kbd_struct * kbd = kbd_table;
  114. static struct tty_struct * tty = NULL;
  115.  
  116. typedef void (*k_hand)(unsigned char value, char up_flag);
  117. typedef void (k_handfn)(unsigned char value, char up_flag);
  118.  
  119. static k_handfn
  120.         do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
  121.     do_meta, do_ascii, do_lock, do_lowercase;
  122.  
  123. static k_hand key_handler[] = {
  124.     do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
  125.     do_meta, do_ascii, do_lock, do_lowercase
  126. };
  127.  
  128. /* maximum values each key_handler can handle */
  129. const int max_vals[] = {
  130.     255, NR_FUNC - 1, 14, 17, 4, 255, 3, NR_SHIFT,
  131.     255, 9, 3, 255
  132. };
  133.  
  134. const int NR_TYPES = SIZE(max_vals);
  135.  
  136. static void put_queue(int);
  137. static unsigned char handle_diacr(unsigned char);
  138.  
  139. #ifdef __notyet__
  140. /* pt_regs - set by keyboard_interrupt(), used by show_ptregs() */
  141. static struct pt_regs * pt_regs;
  142. #endif
  143.  
  144. static int got_break = 0;
  145.  
  146. #ifdef __pc_stuff__
  147.  
  148. static inline void kb_wait(void)
  149. {
  150.     int i;
  151.  
  152.     for (i=0; i<0x10000; i++)
  153.         if ((inb_p(0x64) & 0x02) == 0)
  154.             break;
  155. }
  156.  
  157. static inline void send_cmd(unsigned char c)
  158. {
  159.     kb_wait();
  160.     outb(c,0x64);
  161. }
  162.  
  163. /*
  164.  * Translation of escaped scancodes to keysyms.
  165.  * This should be user-settable.
  166.  */
  167. #define E0_BASE 96
  168.  
  169. #define E0_KPENTER (E0_BASE+0)
  170. #define E0_RCTRL   (E0_BASE+1)
  171. #define E0_KPSLASH (E0_BASE+2)
  172. #define E0_PRSCR   (E0_BASE+3)
  173. #define E0_RALT    (E0_BASE+4)
  174. #define E0_BREAK   (E0_BASE+5)  /* (control-pause) */
  175. #define E0_HOME    (E0_BASE+6)
  176. #define E0_UP      (E0_BASE+7)
  177. #define E0_PGUP    (E0_BASE+8)
  178. #define E0_LEFT    (E0_BASE+9)
  179. #define E0_RIGHT   (E0_BASE+10)
  180. #define E0_END     (E0_BASE+11)
  181. #define E0_DOWN    (E0_BASE+12)
  182. #define E0_PGDN    (E0_BASE+13)
  183. #define E0_INS     (E0_BASE+14)
  184. #define E0_DEL     (E0_BASE+15)
  185. /* BTC */
  186. #define E0_MACRO   (E0_BASE+16)
  187. /* LK450 */
  188. #define E0_F13     (E0_BASE+17)
  189. #define E0_F14     (E0_BASE+18)
  190. #define E0_HELP    (E0_BASE+19)
  191. #define E0_DO      (E0_BASE+20)
  192. #define E0_F17     (E0_BASE+21)
  193. #define E0_KPMINPLUS (E0_BASE+22)
  194.  
  195. #define E1_PAUSE   (E0_BASE+23)
  196.  
  197. static unsigned char e0_keys[128] = {
  198.   0, 0, 0, 0, 0, 0, 0, 0,                  /* 0x00-0x07 */
  199.   0, 0, 0, 0, 0, 0, 0, 0,                  /* 0x08-0x0f */
  200.   0, 0, 0, 0, 0, 0, 0, 0,                  /* 0x10-0x17 */
  201.   0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,          /* 0x18-0x1f */
  202.   0, 0, 0, 0, 0, 0, 0, 0,                  /* 0x20-0x27 */
  203.   0, 0, 0, 0, 0, 0, 0, 0,                  /* 0x28-0x2f */
  204.   0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,          /* 0x30-0x37 */
  205.   E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,          /* 0x38-0x3f */
  206.   E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,          /* 0x40-0x47 */
  207.   E0_UP, E0_PGUP, 0, E0_LEFT, 0, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
  208.   E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,          /* 0x50-0x57 */
  209.   0, 0, 0, 0, 0, 0, 0, 0,                  /* 0x58-0x5f */
  210.   0, 0, 0, 0, 0, 0, 0, 0,                  /* 0x60-0x67 */
  211.   0, 0, 0, 0, 0, 0, 0, E0_MACRO,              /* 0x68-0x6f */
  212.   0, 0, 0, 0, 0, 0, 0, 0,                  /* 0x70-0x77 */
  213.   0, 0, 0, 0, 0, 0, 0, 0                  /* 0x78-0x7f */
  214. };
  215.  
  216. #endif /* __pc_stuff__ */
  217.  
  218. #ifdef __pc_stuff__
  219. static void keyboard_interrupt(int int_pt_regs)
  220. #else
  221. void process_scancode( int scancode )
  222. #endif
  223. {
  224. #ifdef __pc_stuff__
  225.     unsigned char scancode;
  226.     static unsigned int prev_scancode = 0;   /* remember E0, E1 */
  227. #endif
  228.     char up_flag;                         /* 0 or 0200 */
  229.     char raw_mode;
  230.  
  231. #ifdef __pc_stuff__
  232.     pt_regs = (struct pt_regs *) int_pt_regs;
  233.     send_cmd(0xAD);        /* disable keyboard */
  234.     kb_wait();
  235.     if ((inb_p(0x64) & kbd_read_mask) != 0x01)
  236.         goto end_kbd_intr;
  237.     scancode = inb(0x60);
  238. #endif
  239.     mark_bh(KEYBOARD_BH);
  240. #ifdef __pc_stuff__
  241.     if (scancode == 0xfa) {
  242.         acknowledge = 1;
  243.         goto end_kbd_intr;
  244.     } else if (scancode == 0xfe) {
  245.         resend = 1;
  246.         goto end_kbd_intr;
  247.     } else if (scancode == 0) {
  248. #ifdef KBD_REPORT_ERR
  249.             printk("keyboard buffer overflow\n");
  250. #endif
  251.         goto end_kbd_intr;
  252.     } else if (scancode == 0xff) {
  253. #ifdef KBD_REPORT_ERR
  254.             printk("keyboard error\n");
  255. #endif
  256.             prev_scancode = 0;
  257.             goto end_kbd_intr;
  258.     }
  259. #endif /* __pc_stuff__ */
  260.  
  261.     tty = TTY_TABLE(0);
  262.      kbd = kbd_table + fg_console;
  263.     if ((raw_mode = vc_kbd_mode(kbd,VC_RAW))) {
  264.          put_queue(scancode);
  265.         /* we do not return yet, because we want to maintain
  266.            the key_down array, so that we have the correct
  267.            values when finishing RAW mode or when changing VT's */
  268.      }
  269. #ifdef __pc_stuff__
  270.     if (scancode == 0xe0 || scancode == 0xe1) {
  271.         prev_scancode = scancode;
  272.         goto end_kbd_intr;
  273.      }
  274. #endif
  275.  
  276.      /*
  277.      *  Convert scancode to keysym, using prev_scancode.
  278.       */
  279. #ifdef __pc_stuff__
  280.     up_flag = (scancode & 0200);
  281. #else
  282.     up_flag = (scancode & ~0x7f);
  283. #endif
  284.      scancode &= 0x7f;
  285.   
  286. #ifdef __pc_stuff__
  287.     if (prev_scancode) {
  288.       /*
  289.        * usually it will be 0xe0, but a Pause key generates
  290.        * e1 1d 45 e1 9d c5 when pressed, and nothing when released
  291.        */
  292.       if (prev_scancode != 0xe0) {
  293.           if (prev_scancode == 0xe1 && scancode == 0x1d) {
  294.           prev_scancode = 0x100;
  295.           goto end_kbd_intr;
  296.           } else if (prev_scancode == 0x100 && scancode == 0x45) {
  297.           scancode = E1_PAUSE;
  298.           prev_scancode = 0;
  299.           } else {
  300.           printk("keyboard: unknown e1 escape sequence\n");
  301.           prev_scancode = 0;
  302.           goto end_kbd_intr;
  303.           }
  304.       } else {
  305.           prev_scancode = 0;
  306.           /*
  307.            *  The keyboard maintains its own internal caps lock and
  308.            *  num lock statuses. In caps lock mode E0 AA precedes make
  309.            *  code and E0 2A follows break code. In num lock mode,
  310.            *  E0 2A precedes make code and E0 AA follows break code.
  311.            *  We do our own book-keeping, so we will just ignore these.
  312.            */
  313.           /*
  314.            *  For my keyboard there is no caps lock mode, but there are
  315.            *  both Shift-L and Shift-R modes. The former mode generates
  316.            *  E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
  317.            *  So, we should also ignore the latter. - aeb@cwi.nl
  318.            */
  319.           if (scancode == 0x2a || scancode == 0x36)
  320.         goto end_kbd_intr;
  321.  
  322.           if (e0_keys[scancode])
  323.         scancode = e0_keys[scancode];
  324.           else if (!raw_mode) {
  325. #ifdef KBD_REPORT_UNKN
  326.           printk("keyboard: unknown scancode e0 %02x\n", scancode);
  327. #endif
  328.           goto end_kbd_intr;
  329.           }
  330.       }
  331.     } else if (scancode >= E0_BASE && !raw_mode) {
  332. #ifdef KBD_REPORT_UNKN
  333.       printk("keyboard: scancode (%02x) not in range 00 - %2x\n",
  334.          scancode, E0_BASE - 1);
  335. #endif
  336.       goto end_kbd_intr;
  337.      }
  338. #endif /* __pc_stuff__ */
  339.   
  340.     /*
  341.      * At this point the variable `scancode' contains the keysym.
  342.      * We keep track of the up/down status of the key, and
  343.      * return the keysym if in MEDIUMRAW mode.
  344.      * (Note: earlier kernels had a bug and did not pass the up/down
  345.      * bit to applications.)
  346.      */
  347.  
  348.     if (up_flag) {
  349.          clear_bit(scancode, key_down);
  350.         rep = 0;
  351.     } else
  352.          rep = set_bit(scancode, key_down);
  353.   
  354.     if (raw_mode)
  355.             goto end_kbd_intr;
  356.  
  357.      if (vc_kbd_mode(kbd, VC_MEDIUMRAW)) {
  358.          put_queue(scancode + up_flag);
  359.         goto end_kbd_intr;
  360.      }
  361.   
  362.      /*
  363.      * Small change in philosophy: earlier we defined repetition by
  364.      *     rep = scancode == prev_keysym;
  365.      *     prev_keysym = scancode;
  366.      * but now by the fact that the depressed key was down already.
  367.      * Does this ever make a difference?
  368.      */
  369.  
  370.     /*
  371.       *  Repeat a key only if the input buffers are empty or the
  372.       *  characters get echoed locally. This makes key repeat usable
  373.       *  with slow applications and under heavy loads.
  374.      */
  375.     if (!rep || 
  376.         (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
  377.          (L_ECHO(tty) || (EMPTY(&tty->secondary) && EMPTY(&tty->read_q)))))
  378.     {
  379.         u_short key_code;
  380.         u_char type;
  381.  
  382.         /* the XOR below used to be an OR */
  383.         int shift_final = shift_state ^ kbd->lockstate;
  384.  
  385.         key_code = key_map[shift_final][scancode];
  386.         type = KTYP(key_code);
  387.  
  388.         if (type == KT_LETTER) {
  389.             type = KT_LATIN;
  390.             if (vc_kbd_led(kbd,VC_CAPSLOCK))
  391.             key_code = key_map[shift_final ^ (1<<KG_SHIFT)][scancode];
  392.         }
  393.         (*key_handler[type])(key_code & 0xff, up_flag);
  394.     }
  395.  
  396. end_kbd_intr:
  397. #ifdef __pc_stuff__
  398.     send_cmd(0xAE);         /* enable keyboard */
  399. #endif
  400. }
  401.  
  402. static void put_queue(int ch)
  403. {
  404.     struct tty_queue *qp;
  405.  
  406.     wake_up(&keypress_wait);
  407.     if (!tty)
  408.         return;
  409.     qp = &tty->read_q;
  410.  
  411.     if (LEFT(qp)) {
  412.         qp->buf[qp->head] = ch;
  413.         INC(qp->head);
  414.         wake_up_interruptible(&qp->proc_list);
  415.     }
  416. }
  417.  
  418. static void puts_queue(char *cp)
  419. {
  420.     struct tty_queue *qp;
  421.     char ch;
  422.  
  423.     /* why interruptible here, plain wake_up above? */
  424.     wake_up_interruptible(&keypress_wait);
  425.     if (!tty)
  426.         return;
  427.     qp = &tty->read_q;
  428.  
  429.     while ((ch = *(cp++)) != 0) {
  430.         if (LEFT(qp)) {
  431.             qp->buf[qp->head] = ch;
  432.             INC(qp->head);
  433.         }
  434.     }
  435.     wake_up_interruptible(&qp->proc_list);
  436. }
  437.  
  438. static void applkey(int key, char mode)
  439. {
  440.     static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
  441.  
  442.     buf[1] = (mode ? 'O' : '[');
  443.     buf[2] = key;
  444.     puts_queue(buf);
  445. }
  446.  
  447. static void enter(void)
  448. {
  449.     put_queue(13);
  450.     if (vc_kbd_mode(kbd,VC_CRLF))
  451.         put_queue(10);
  452. }
  453.  
  454. static void caps_toggle(void)
  455. {
  456.     if (rep)
  457.         return;
  458.     chg_vc_kbd_led(kbd,VC_CAPSLOCK);
  459. }
  460.  
  461. static void caps_on(void)
  462. {
  463.     if (rep)
  464.         return;
  465.     set_vc_kbd_led(kbd,VC_CAPSLOCK);
  466. }
  467.  
  468. static void show_ptregs(void)
  469. {
  470. #ifdef notyet
  471.  
  472.     /* Printing the registers is not so easy for m68k, because the
  473.      * interrupt handler (from which this is called) save just
  474.      * d0-d1/a0-a1, sr and pc (others are saved by gcc when
  475.      * needed). We could print these here, but that's incomplete.
  476.      * Let's think over a while for some better method...
  477.      */
  478.     
  479.     if (!pt_regs)
  480.         return;
  481.     printk("\n");
  482.     printk("EIP: %04x:%08lx",0xffff & pt_regs->cs,pt_regs->eip);
  483.     if (pt_regs->cs & 3)
  484.         printk(" ESP: %04x:%08lx",0xffff & pt_regs->ss,pt_regs->esp);
  485.     printk(" EFLAGS: %08lx\n",pt_regs->eflags);
  486.     printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
  487.         pt_regs->orig_eax,pt_regs->ebx,pt_regs->ecx,pt_regs->edx);
  488.     printk("ESI: %08lx EDI: %08lx EBP: %08lx",
  489.         pt_regs->esi, pt_regs->edi, pt_regs->ebp);
  490.     printk(" DS: %04x ES: %04x FS: %04x GS: %04x\n",
  491.         0xffff & pt_regs->ds,0xffff & pt_regs->es,
  492.         0xffff & pt_regs->fs,0xffff & pt_regs->gs);
  493. #endif
  494. }
  495.  
  496. static void hold(void)
  497. {
  498.     if (rep || !tty)
  499.         return;
  500.  
  501.     /*
  502.      * Note: SCROLLOCK wil be set (cleared) by stop_tty (start_tty);
  503.      * these routines are also activated by ^S/^Q.
  504.      * (And SCROLLOCK can also be set by the ioctl KDSETLED.)
  505.      */
  506.     if (tty->stopped)
  507.         start_tty(tty);
  508.     else
  509.         stop_tty(tty);
  510. }
  511.  
  512. #if 0
  513. /* unused at present - and the VC_PAUSE bit is not used anywhere either */
  514. static void pause(void)
  515. {
  516.     chg_vc_kbd_mode(kbd,VC_PAUSE);
  517. }
  518. #endif
  519.  
  520. static void num(void)
  521. {
  522.     if (vc_kbd_mode(kbd,VC_APPLIC)) {
  523.         applkey('P', 1);
  524.         return;
  525.     }
  526.     if (!rep)    /* no autorepeat for numlock, ChN */
  527.         chg_vc_kbd_led(kbd,VC_NUMLOCK);
  528. }
  529.  
  530. static void lastcons(void)
  531. {
  532.     /* pressing alt-printscreen switches to the last used console, ChN */
  533.     want_console = last_console;
  534. }
  535.  
  536. static void send_intr(void)
  537. {
  538.     got_break = 1;
  539. }
  540.  
  541. static void scrll_forw(void)
  542. {
  543.     scrollfront(0);
  544. }
  545.  
  546. static void scrll_back(void)
  547. {
  548.     scrollback(0);
  549. }
  550.  
  551. static void boot_it(void)
  552. {
  553.     ctrl_alt_del();
  554. }
  555.  
  556. static void compose(void)
  557. {
  558.         dead_key_next = 1;
  559. }
  560.  
  561. static void do_spec(unsigned char value, char up_flag)
  562. {
  563.     typedef void (*fnp)(void);
  564.     fnp fn_table[] = {
  565.         NULL,        enter,        show_ptregs,    show_mem,
  566.         show_state,    send_intr,    lastcons,    caps_toggle,
  567.         num,        hold,        scrll_forw,    scrll_back,
  568.         boot_it,    caps_on,        compose
  569.     };
  570.  
  571.     if (up_flag)
  572.         return;
  573.     if (value >= SIZE(fn_table))
  574.         return;
  575.     if (!fn_table[value])
  576.         return;
  577.     fn_table[value]();
  578. }
  579.  
  580. static void do_lowercase(unsigned char value, char up_flag)
  581. {
  582.         printk("keyboard.c: do_lowercase was called - impossible\n");
  583. }
  584.   
  585. static void do_self(unsigned char value, char up_flag)
  586. {
  587.     if (up_flag)
  588.         return;        /* no action, if this is a key release */
  589.  
  590.         if (diacr)
  591.                 value = handle_diacr(value);
  592.  
  593.         if (dead_key_next) {
  594.                 dead_key_next = 0;
  595.                 diacr = value;
  596.                 return;
  597.         }
  598.  
  599.     put_queue(value);
  600. }
  601.  
  602. #define A_GRAVE  '`'
  603. #define A_ACUTE  '\''
  604. #define A_CFLEX  '^'
  605. #define A_TILDE  '~'
  606. #define A_DIAER  '"'
  607. static unsigned char ret_diacr[] =
  608.         {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER };
  609.  
  610. /* If a dead key pressed twice, output a character corresponding to it,    */
  611. /* otherwise just remember the dead key.                */
  612.  
  613. static void do_dead(unsigned char value, char up_flag)
  614. {
  615.     if (up_flag)
  616.         return;
  617.  
  618.         value = ret_diacr[value];
  619.         if (diacr == value) {   /* pressed twice */
  620.                 diacr = 0;
  621.                 put_queue(value);
  622.                 return;
  623.         }
  624.     diacr = value;
  625. }
  626.  
  627.  
  628. /* If space is pressed, return the character corresponding the pending    */
  629. /* dead key, otherwise try to combine the two.                */
  630.  
  631. unsigned char handle_diacr(unsigned char ch)
  632. {
  633.         int d = diacr;
  634.         int i;
  635.  
  636.         diacr = 0;
  637.         if (ch == ' ')
  638.                 return d;
  639.  
  640.         for (i = 0; i < accent_table_size; i++)
  641.           if(accent_table[i].diacr == d && accent_table[i].base == ch)
  642.             return accent_table[i].result;
  643.  
  644.         put_queue(d);
  645.         return ch;
  646. }
  647.  
  648. static void do_cons(unsigned char value, char up_flag)
  649. {
  650.     if (up_flag)
  651.         return;
  652.     want_console = value;
  653. }
  654.  
  655. static void do_fn(unsigned char value, char up_flag)
  656. {
  657.     if (up_flag)
  658.         return;
  659.     if (value < SIZE(func_table))
  660.             puts_queue(func_table[value]);
  661.     else
  662.             printk("do_fn called with value=%d\n", value);
  663. }
  664.  
  665. static void do_pad(unsigned char value, char up_flag)
  666. {
  667.     static char *pad_chars = "0123456789+-*/\015,.?";
  668.     static char *app_map = "pqrstuvwxylSRQMnn?";
  669.  
  670.     if (up_flag)
  671.         return;        /* no action, if this is a key release */
  672.  
  673.     /* kludge... shift forces cursor/number keys */
  674.     if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
  675.         applkey(app_map[value], 1);
  676.         return;
  677.     }
  678.  
  679.     if (!vc_kbd_led(kbd,VC_NUMLOCK))
  680.         switch (value) {
  681.             case KVAL(K_PCOMMA):
  682.             case KVAL(K_PDOT):
  683.                 do_fn(KVAL(K_REMOVE), 0);
  684.                 return;
  685.             case KVAL(K_P0):
  686.                 do_fn(KVAL(K_INSERT), 0);
  687.                 return;
  688.             case KVAL(K_P1):
  689.                 do_fn(KVAL(K_SELECT), 0);
  690.                 return;
  691.             case KVAL(K_P2):
  692.                 do_cur(KVAL(K_DOWN), 0);
  693.                 return;
  694.             case KVAL(K_P3):
  695.                 do_fn(KVAL(K_PGDN), 0);
  696.                 return;
  697.             case KVAL(K_P4):
  698.                 do_cur(KVAL(K_LEFT), 0);
  699.                 return;
  700.             case KVAL(K_P6):
  701.                 do_cur(KVAL(K_RIGHT), 0);
  702.                 return;
  703.             case KVAL(K_P7):
  704.                 do_fn(KVAL(K_FIND), 0);
  705.                 return;
  706.             case KVAL(K_P8):
  707.                 do_cur(KVAL(K_UP), 0);
  708.                 return;
  709.             case KVAL(K_P9):
  710.                 do_fn(KVAL(K_PGUP), 0);
  711.                 return;
  712.             case KVAL(K_P5):
  713.                 applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
  714.                 return;
  715.         }
  716.  
  717.     put_queue(pad_chars[value]);
  718.     if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
  719.         put_queue(10);
  720. }
  721.  
  722. static void do_cur(unsigned char value, char up_flag)
  723. {
  724.     static char *cur_chars = "BDCA";
  725.     if (up_flag)
  726.         return;
  727.  
  728.     applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
  729. }
  730.  
  731. static void do_shift(unsigned char value, char up_flag)
  732. {
  733.     int old_state = shift_state;
  734.  
  735.     if (rep)
  736.         return;
  737.  
  738.     /* kludge... */
  739.     if (value == KVAL(K_CAPSSHIFT)) {
  740.         value = KVAL(K_SHIFT);
  741.         clr_vc_kbd_led(kbd, VC_CAPSLOCK);
  742.     }
  743.  
  744.     if (up_flag) {
  745.             /* handle the case that two shift or control
  746.            keys are depressed simultaneously */
  747.         if (k_down[value])
  748.             k_down[value]--;
  749.     } else
  750.         k_down[value]++;
  751.  
  752.     if (k_down[value])
  753.         shift_state |= (1 << value);
  754.     else
  755.         shift_state &= ~ (1 << value);
  756.  
  757.     /* kludge */
  758.     if (up_flag && shift_state != old_state && npadch != -1) {
  759.         put_queue(npadch);
  760.         npadch = -1;
  761.     }
  762. }
  763.  
  764. /* called after returning from RAW mode or when changing consoles -
  765.    recompute k_down[] and shift_state from key_down[] */
  766. void compute_shiftstate(void)
  767. {
  768.         int i, j, k, sym, val;
  769.  
  770.         shift_state = 0;
  771.     for(i=0; i < SIZE(k_down); i++)
  772.       k_down[i] = 0;
  773.  
  774.     for(i=0; i < SIZE(key_down); i++)
  775.       if(key_down[i]) {    /* skip this word if not a single bit on */
  776.         k = (i<<5);
  777.         for(j=0; j<32; j++,k++)
  778.           if(test_bit(k, key_down)) {
  779.         sym = key_map[0][k];
  780.         if(KTYP(sym) == KT_SHIFT) {
  781.           val = KVAL(sym);
  782.           k_down[val]++;
  783.           shift_state |= (1<<val);
  784.             }
  785.           }
  786.       }
  787. }
  788.  
  789. static void do_meta(unsigned char value, char up_flag)
  790. {
  791.     if (up_flag)
  792.         return;
  793.  
  794.     if (vc_kbd_mode(kbd, VC_META)) {
  795.         put_queue('\033');
  796.         put_queue(value);
  797.     } else
  798.         put_queue(value | 0x80);
  799. }
  800.  
  801. static void do_ascii(unsigned char value, char up_flag)
  802. {
  803.     if (up_flag)
  804.         return;
  805.  
  806.     if (npadch == -1)
  807.             npadch = value;
  808.     else
  809.             npadch = (npadch * 10 + value) % 1000;
  810. }
  811.  
  812. static void do_lock(unsigned char value, char up_flag)
  813. {
  814.     if (up_flag || rep)
  815.         return;
  816.     chg_vc_kbd_lock(kbd, value);
  817. }
  818.  
  819. #ifdef __pc_stuff__
  820. /*
  821.  * send_data sends a character to the keyboard and waits
  822.  * for a acknowledge, possibly retrying if asked to. Returns
  823.  * the success status.
  824.  */
  825. static int send_data(unsigned char data)
  826. {
  827.     int retries = 3;
  828.     int i;
  829.  
  830.     do {
  831.         kb_wait();
  832.         acknowledge = 0;
  833.         resend = 0;
  834.         outb_p(data, 0x60);
  835.         for(i=0; i<0x20000; i++) {
  836.             inb_p(0x64);        /* just as a delay */
  837.             if (acknowledge)
  838.                 return 1;
  839.             if (resend)
  840.                 break;
  841.         }
  842.         if (!resend)
  843.             return 0;
  844.     } while (retries-- > 0);
  845.     return 0;
  846. }
  847. #endif /* __pc_stuff__ */
  848.  
  849. /*
  850.  * This routine is the bottom half of the keyboard interrupt
  851.  * routine, and runs with all interrupts enabled. It does
  852.  * console changing, led setting and copy_to_cooked, which can
  853.  * take a reasonably long time.
  854.  *
  855.  * Aside from timing (which isn't really that important for
  856.  * keyboard interrupts as they happen often), using the software
  857.  * interrupt routines for this thing allows us to easily mask
  858.  * this when we don't want any of the above to happen. Not yet
  859.  * used, but this allows for easy and efficient race-condition
  860.  * prevention later on.
  861.  */
  862. static void kbd_bh(void * unused)
  863. {
  864. #ifdef __pc_stuff__
  865.     static unsigned char old_leds = 0xff;
  866.     unsigned char leds = kbd_table[fg_console].ledstate;
  867.  
  868.     if (leds != old_leds) {
  869.         old_leds = leds;
  870.         if (!send_data(0xed) || !send_data(leds))
  871.             send_data(0xf4);    /* re-enable kbd if any errors */
  872.     }
  873. #endif
  874.  
  875.     if (want_console >= 0) {
  876.         if (want_console != fg_console) {
  877.             last_console = fg_console;
  878.             change_console(want_console);
  879.         }
  880.         want_console = -1;
  881.     }
  882.     if (got_break) {
  883.         if (tty && !I_IGNBRK(tty)) {
  884.             if (I_BRKINT(tty)) {
  885.                 flush_input(tty);
  886.                 flush_output(tty);
  887.                 if (tty->pgrp > 0)
  888.                     kill_pg(tty->pgrp, SIGINT, 1);
  889.             } else {
  890.                 cli();
  891.                 if (LEFT(&tty->read_q) >= 2) {
  892.                     set_bit(tty->read_q.head,
  893.                         &tty->readq_flags);
  894.                     put_queue(TTY_BREAK);
  895.                     put_queue(0);
  896.                 }
  897.                 sti();
  898.             }
  899.         }
  900.         got_break = 0;
  901.     }
  902.     do_keyboard_interrupt();
  903.  
  904. #ifdef __pc_stuff__
  905.     cli();
  906.     if ((inb_p(0x64) & kbd_read_mask) == 0x01)
  907.         fake_keyboard_interrupt();
  908.     sti();
  909. #endif
  910.  
  911. }
  912.  
  913. #ifdef __pc_stuff__
  914.  
  915. /* hard_reset_now() still exists, but is moved to device-dependant code */
  916.  
  917. long no_idt[2] = {0, 0};
  918.  
  919. /*
  920.  * This routine reboots the machine by asking the keyboard
  921.  * controller to pulse the reset-line low. We try that for a while,
  922.  * and if it doesn't work, we do some other stupid things.
  923.  */
  924. void hard_reset_now(void)
  925. {
  926.     int i, j;
  927.     extern unsigned long pg0[1024];
  928.  
  929.     sti();
  930. /* rebooting needs to touch the page at absolute addr 0 */
  931.     pg0[0] = 7;
  932.     *((unsigned short *)0x472) = 0x1234;
  933.     for (;;) {
  934.         for (i=0; i<100; i++) {
  935.             kb_wait();
  936.             for(j = 0; j < 100000 ; j++)
  937.                 /* nothing */;
  938.             outb(0xfe,0x64);     /* pulse reset low */
  939.         }
  940.         __asm__("\tlidt _no_idt");
  941.     }
  942. }
  943.  
  944. #endif /* __pc_stuff__ */
  945.  
  946.  
  947. unsigned long kbd_init(unsigned long kmem_start)
  948. {
  949.     int i;
  950.     struct kbd_struct * kbd;
  951.  
  952.     kbd = kbd_table + 0;
  953.     for (i = 0 ; i < NR_CONSOLES ; i++,kbd++) {
  954.         kbd->ledstate = KBD_DEFLEDS;
  955.         kbd->default_ledstate = KBD_DEFLEDS;
  956.         kbd->lockstate = KBD_DEFLOCK;
  957.         kbd->modeflags = KBD_DEFMODE;
  958.     }
  959.  
  960.     bh_base[KEYBOARD_BH].routine = kbd_bh;
  961. #ifdef __pc_stuf__
  962.     request_irq(KEYBOARD_IRQ,keyboard_interrupt);
  963. #endif
  964.     mark_bh(KEYBOARD_BH);
  965. #ifdef __pc_stuf__
  966.     return kmem_start;
  967. #else
  968.     return mach_keyb_init (kmem_start);
  969. #endif
  970. }
  971.