This source file includes following definitions.
- kb_wait
- send_cmd
- to_utf8
- setkeycode
- getkeycode
- keyboard_interrupt
- put_queue
- puts_queue
- applkey
- enter
- caps_toggle
- caps_on
- show_ptregs
- hold
- num
- lastcons
- decr_console
- incr_console
- send_intr
- scroll_forw
- scroll_back
- boot_it
- compose
- spawn_console
- SAK
- do_ignore
- do_null
- do_spec
- do_lowercase
- do_self
- do_dead
- handle_diacr
- do_cons
- do_fn
- do_pad
- do_cur
- do_shift
- compute_shiftstate
- do_meta
- do_ascii
- do_lock
- send_data
- getledstate
- setledstate
- register_leds
- getleds
- kbd_bh
- kbd_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
41
42 #ifndef KBD_DEFMODE
43 #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
44 #endif
45
46 #ifndef KBD_DEFLEDS
47
48
49
50
51 #define KBD_DEFLEDS 0
52 #endif
53
54 #ifndef KBD_DEFLOCK
55 #define KBD_DEFLOCK 0
56 #endif
57
58
59
60
61
62
63
64 #define REALLY_SLOW_IO
65 #define SLOW_IO_BY_JUMPING
66 #include <asm/io.h>
67 #include <asm/system.h>
68
69 extern void poke_blanked_console(void);
70 extern void ctrl_alt_del(void);
71 extern void reset_vc(unsigned int new_console);
72 extern void change_console(unsigned int new_console);
73 extern void scrollback(int);
74 extern void scrollfront(int);
75 extern int vc_cons_allocated(unsigned int);
76
77 #ifdef __i386__
78 #define fake_keyboard_interrupt() __asm__ __volatile__("int $0x21")
79 #else
80 #define fake_keyboard_interrupt() do ; while (0)
81 #endif
82
83 unsigned char kbd_read_mask = 0x01;
84
85
86
87
88
89
90
91
92 static unsigned char k_down[NR_SHIFT] = {0, };
93
94 static unsigned long key_down[8] = { 0, };
95
96 extern int last_console;
97 static int want_console = -1;
98 static int dead_key_next = 0;
99
100
101
102
103
104 int shift_state = 0;
105 static int npadch = -1;
106 static unsigned char diacr = 0;
107 static char rep = 0;
108 struct kbd_struct kbd_table[MAX_NR_CONSOLES];
109 static struct tty_struct **ttytab;
110 static struct kbd_struct * kbd = kbd_table;
111 static struct tty_struct * tty = NULL;
112
113
114 static volatile unsigned char reply_expected = 0;
115 static volatile unsigned char acknowledge = 0;
116 static volatile unsigned char resend = 0;
117
118 extern void compute_shiftstate(void);
119
120 typedef void (*k_hand)(unsigned char value, char up_flag);
121 typedef void (k_handfn)(unsigned char value, char up_flag);
122
123 static k_handfn
124 do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
125 do_meta, do_ascii, do_lock, do_lowercase, do_ignore;
126
127 static k_hand key_handler[16] = {
128 do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
129 do_meta, do_ascii, do_lock, do_lowercase,
130 do_ignore, do_ignore, do_ignore, do_ignore
131 };
132
133 typedef void (*void_fnp)(void);
134 typedef void (void_fn)(void);
135
136 static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle,
137 num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose,
138 SAK, decr_console, incr_console, spawn_console;
139
140 static void_fnp spec_fn_table[] = {
141 do_null, enter, show_ptregs, show_mem,
142 show_state, send_intr, lastcons, caps_toggle,
143 num, hold, scroll_forw, scroll_back,
144 boot_it, caps_on, compose, SAK,
145 decr_console, incr_console, spawn_console
146 };
147
148
149 const int max_vals[] = {
150 255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
151 NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
152 255, NR_ASCII - 1, NR_LOCK - 1, 255
153 };
154
155 const int NR_TYPES = SIZE(max_vals);
156
157 static void put_queue(int);
158 static unsigned char handle_diacr(unsigned char);
159
160
161 static struct pt_regs * pt_regs;
162
163 static inline void kb_wait(void)
164 {
165 int i;
166
167 for (i=0; i<0x100000; i++)
168 if ((inb_p(0x64) & 0x02) == 0)
169 return;
170 printk("Keyboard timed out\n");
171 }
172
173 static inline void send_cmd(unsigned char c)
174 {
175 kb_wait();
176 outb(c,0x64);
177 }
178
179
180
181
182
183
184
185 void to_utf8(ushort c) {
186 if (c < 0x80)
187 put_queue(c);
188 else if (c < 0x800) {
189 put_queue(0xc0 | (c >> 6));
190 put_queue(0x80 | (c & 0x3f));
191 } else {
192 put_queue(0xe0 | (c >> 12));
193 put_queue(0x80 | ((c >> 6) & 0x3f));
194 put_queue(0x80 | (c & 0x3f));
195 }
196
197
198 }
199
200
201
202
203
204
205
206
207
208
209
210 #define E0_KPENTER 96
211 #define E0_RCTRL 97
212 #define E0_KPSLASH 98
213 #define E0_PRSCR 99
214 #define E0_RALT 100
215 #define E0_BREAK 101
216 #define E0_HOME 102
217 #define E0_UP 103
218 #define E0_PGUP 104
219 #define E0_LEFT 105
220 #define E0_RIGHT 106
221 #define E0_END 107
222 #define E0_DOWN 108
223 #define E0_PGDN 109
224 #define E0_INS 110
225 #define E0_DEL 111
226
227 #define E1_PAUSE 119
228
229
230
231
232
233
234
235
236 #define SC_LIM 89
237
238 #define FOCUS_PF1 85
239 #define FOCUS_PF2 89
240 #define FOCUS_PF3 90
241 #define FOCUS_PF4 91
242 #define FOCUS_PF5 92
243 #define FOCUS_PF6 93
244 #define FOCUS_PF7 94
245 #define FOCUS_PF8 95
246 #define FOCUS_PF9 120
247 #define FOCUS_PF10 121
248 #define FOCUS_PF11 122
249 #define FOCUS_PF12 123
250
251 #define JAP_86 124
252
253
254
255
256
257
258 #define RGN1 124
259 #define RGN2 125
260 #define RGN3 126
261 #define RGN4 127
262
263 static unsigned char high_keys[128 - SC_LIM] = {
264 RGN1, RGN2, RGN3, RGN4, 0, 0, 0,
265 0, 0, 0, 0, 0, 0, 0, 0,
266 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,
267 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,
268 FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,
269 FOCUS_PF8, JAP_86, FOCUS_PF10, 0
270 };
271
272
273 #define E0_MACRO 112
274
275 #define E0_F13 113
276 #define E0_F14 114
277 #define E0_HELP 115
278 #define E0_DO 116
279 #define E0_F17 117
280 #define E0_KPMINPLUS 118
281
282
283
284
285 #define E0_OK 124
286
287
288
289
290
291
292 #define E0_MSLW 125
293 #define E0_MSRW 126
294 #define E0_MSTM 127
295
296 static unsigned char e0_keys[128] = {
297 0, 0, 0, 0, 0, 0, 0, 0,
298 0, 0, 0, 0, 0, 0, 0, 0,
299 0, 0, 0, 0, 0, 0, 0, 0,
300 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,
301 0, 0, 0, 0, 0, 0, 0, 0,
302 0, 0, 0, 0, 0, 0, 0, 0,
303 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,
304 E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,
305 E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,
306 E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,
307 E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,
308 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,
309 0, 0, 0, 0, 0, 0, 0, 0,
310 0, 0, 0, 0, 0, 0, 0, E0_MACRO,
311 0, 0, 0, 0, 0, 0, 0, 0,
312 0, 0, 0, 0, 0, 0, 0, 0
313 };
314
315 int setkeycode(unsigned int scancode, unsigned int keycode)
316 {
317 if (scancode < SC_LIM || scancode > 255 || keycode > 127)
318 return -EINVAL;
319 if (scancode < 128)
320 high_keys[scancode - SC_LIM] = keycode;
321 else
322 e0_keys[scancode - 128] = keycode;
323 return 0;
324 }
325
326 int getkeycode(unsigned int scancode)
327 {
328 return
329 (scancode < SC_LIM || scancode > 255) ? -EINVAL :
330 (scancode < 128) ? high_keys[scancode - SC_LIM] :
331 e0_keys[scancode - 128];
332 }
333
334 static void keyboard_interrupt(int irq, struct pt_regs *regs)
335 {
336 unsigned char scancode, keycode;
337 static unsigned int prev_scancode = 0;
338 char up_flag;
339 char raw_mode;
340
341 pt_regs = regs;
342 send_cmd(0xAD);
343 kb_wait();
344 if ((inb_p(0x64) & kbd_read_mask) != 0x01)
345 goto end_kbd_intr;
346 scancode = inb(0x60);
347 mark_bh(KEYBOARD_BH);
348 if (reply_expected) {
349
350
351 reply_expected = 0;
352 if (scancode == 0xfa) {
353 acknowledge = 1;
354 goto end_kbd_intr;
355 } else if (scancode == 0xfe) {
356 resend = 1;
357 goto end_kbd_intr;
358 }
359
360 reply_expected = 1;
361 #if 0
362 printk("keyboard reply expected - got %02x\n", scancode);
363 #endif
364 }
365 if (scancode == 0) {
366 #ifdef KBD_REPORT_ERR
367 printk("keyboard buffer overflow\n");
368 #endif
369 prev_scancode = 0;
370 goto end_kbd_intr;
371 }
372 if (scancode == 0xff) {
373
374 #ifndef KBD_IS_FOCUS_9000
375 #ifdef KBD_REPORT_ERR
376 printk("keyboard error\n");
377 #endif
378 #endif
379 prev_scancode = 0;
380 goto end_kbd_intr;
381 }
382
383 tty = ttytab[fg_console];
384 kbd = kbd_table + fg_console;
385 if ((raw_mode = (kbd->kbdmode == VC_RAW))) {
386 put_queue(scancode);
387
388
389
390 }
391 if (scancode == 0xe0 || scancode == 0xe1) {
392 prev_scancode = scancode;
393 goto end_kbd_intr;
394 }
395
396
397
398
399 up_flag = (scancode & 0200);
400 scancode &= 0x7f;
401
402 if (prev_scancode) {
403
404
405
406
407 if (prev_scancode != 0xe0) {
408 if (prev_scancode == 0xe1 && scancode == 0x1d) {
409 prev_scancode = 0x100;
410 goto end_kbd_intr;
411 } else if (prev_scancode == 0x100 && scancode == 0x45) {
412 keycode = E1_PAUSE;
413 prev_scancode = 0;
414 } else {
415 #ifdef KBD_REPORT_UNKN
416 printk("keyboard: unknown e1 escape sequence\n");
417 #endif
418 prev_scancode = 0;
419 goto end_kbd_intr;
420 }
421 } else {
422 prev_scancode = 0;
423
424
425
426
427
428
429
430
431
432
433
434
435
436 if (scancode == 0x2a || scancode == 0x36)
437 goto end_kbd_intr;
438
439 if (e0_keys[scancode])
440 keycode = e0_keys[scancode];
441 else {
442 #ifdef KBD_REPORT_UNKN
443 if (!raw_mode)
444 printk("keyboard: unknown scancode e0 %02x\n", scancode);
445 #endif
446 goto end_kbd_intr;
447 }
448 }
449 } else if (scancode >= SC_LIM) {
450
451
452
453
454
455
456
457
458
459
460 keycode = high_keys[scancode - SC_LIM];
461
462 if (!keycode) {
463 if (!raw_mode) {
464 #ifdef KBD_REPORT_UNKN
465 printk("keyboard: unrecognized scancode (%02x) - ignored\n"
466 , scancode);
467 #endif
468 }
469 goto end_kbd_intr;
470 }
471 } else
472 keycode = scancode;
473
474
475
476
477
478
479
480
481 if (up_flag) {
482 rep = 0;
483 if(!clear_bit(keycode, key_down)) {
484
485
486
487
488 if (keycode >= SC_LIM || keycode == 85)
489 up_flag = 0;
490 }
491 } else
492 rep = set_bit(keycode, key_down);
493
494 if (raw_mode)
495 goto end_kbd_intr;
496
497 if (kbd->kbdmode == VC_MEDIUMRAW) {
498
499 put_queue(keycode + up_flag);
500 goto end_kbd_intr;
501 }
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516 if (!rep ||
517 (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
518 (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
519 u_short keysym;
520 u_char type;
521
522
523 int shift_final = shift_state ^ kbd->lockstate;
524 ushort *key_map = key_maps[shift_final];
525
526 if (key_map != NULL) {
527 keysym = key_map[keycode];
528 type = KTYP(keysym);
529
530 if (type >= 0xf0) {
531 type -= 0xf0;
532 if (type == KT_LETTER) {
533 type = KT_LATIN;
534 if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
535 key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
536 if (key_map)
537 keysym = key_map[keycode];
538 }
539 }
540 (*key_handler[type])(keysym & 0xff, up_flag);
541 } else {
542
543 if (!up_flag)
544 to_utf8(keysym);
545 }
546 } else {
547
548
549 #if 1
550 compute_shiftstate();
551 #else
552 keysym = U(plain_map[keycode]);
553 type = KTYP(keysym);
554 if (type == KT_SHIFT)
555 (*key_handler[type])(keysym & 0xff, up_flag);
556 #endif
557 }
558 }
559
560 end_kbd_intr:
561 send_cmd(0xAE);
562 }
563
564 static void put_queue(int ch)
565 {
566 wake_up(&keypress_wait);
567 if (tty) {
568 tty_insert_flip_char(tty, ch, 0);
569 tty_schedule_flip(tty);
570 }
571 }
572
573 static void puts_queue(char *cp)
574 {
575 wake_up(&keypress_wait);
576 if (!tty)
577 return;
578
579 while (*cp) {
580 tty_insert_flip_char(tty, *cp, 0);
581 cp++;
582 }
583 tty_schedule_flip(tty);
584 }
585
586 static void applkey(int key, char mode)
587 {
588 static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
589
590 buf[1] = (mode ? 'O' : '[');
591 buf[2] = key;
592 puts_queue(buf);
593 }
594
595 static void enter(void)
596 {
597 put_queue(13);
598 if (vc_kbd_mode(kbd,VC_CRLF))
599 put_queue(10);
600 }
601
602 static void caps_toggle(void)
603 {
604 if (rep)
605 return;
606 chg_vc_kbd_led(kbd, VC_CAPSLOCK);
607 }
608
609 static void caps_on(void)
610 {
611 if (rep)
612 return;
613 set_vc_kbd_led(kbd, VC_CAPSLOCK);
614 }
615
616 static void show_ptregs(void)
617 {
618 if (pt_regs)
619 show_regs(pt_regs);
620 }
621
622 static void hold(void)
623 {
624 if (rep || !tty)
625 return;
626
627
628
629
630
631
632 if (tty->stopped)
633 start_tty(tty);
634 else
635 stop_tty(tty);
636 }
637
638 static void num(void)
639 {
640 if (vc_kbd_mode(kbd,VC_APPLIC)) {
641 applkey('P', 1);
642 return;
643 }
644 if (!rep)
645 chg_vc_kbd_led(kbd,VC_NUMLOCK);
646 }
647
648 static void lastcons(void)
649 {
650
651 want_console = last_console;
652 }
653
654 static void decr_console(void)
655 {
656 int i;
657
658 for (i = fg_console-1; i != fg_console; i--) {
659 if (i == -1)
660 i = MAX_NR_CONSOLES-1;
661 if (vc_cons_allocated(i))
662 break;
663 }
664 want_console = i;
665 }
666
667 static void incr_console(void)
668 {
669 int i;
670
671 for (i = fg_console+1; i != fg_console; i++) {
672 if (i == MAX_NR_CONSOLES)
673 i = 0;
674 if (vc_cons_allocated(i))
675 break;
676 }
677 want_console = i;
678 }
679
680 static void send_intr(void)
681 {
682 if (!tty)
683 return;
684 tty_insert_flip_char(tty, 0, TTY_BREAK);
685 tty_schedule_flip(tty);
686 }
687
688 static void scroll_forw(void)
689 {
690 scrollfront(0);
691 }
692
693 static void scroll_back(void)
694 {
695 scrollback(0);
696 }
697
698 static void boot_it(void)
699 {
700 ctrl_alt_del();
701 }
702
703 static void compose(void)
704 {
705 dead_key_next = 1;
706 }
707
708 int spawnpid, spawnsig;
709
710 static void spawn_console(void)
711 {
712 if (spawnpid)
713 if(kill_proc(spawnpid, spawnsig, 1))
714 spawnpid = 0;
715 }
716
717 static void SAK(void)
718 {
719 do_SAK(tty);
720 #if 0
721
722
723
724
725
726
727
728
729
730 reset_vc(fg_console);
731 unblank_screen();
732 #endif
733 }
734
735 static void do_ignore(unsigned char value, char up_flag)
736 {
737 }
738
739 static void do_null()
740 {
741 compute_shiftstate();
742 }
743
744 static void do_spec(unsigned char value, char up_flag)
745 {
746 if (up_flag)
747 return;
748 if (value >= SIZE(spec_fn_table))
749 return;
750 spec_fn_table[value]();
751 }
752
753 static void do_lowercase(unsigned char value, char up_flag)
754 {
755 printk("keyboard.c: do_lowercase was called - impossible\n");
756 }
757
758 static void do_self(unsigned char value, char up_flag)
759 {
760 if (up_flag)
761 return;
762
763 if (diacr)
764 value = handle_diacr(value);
765
766 if (dead_key_next) {
767 dead_key_next = 0;
768 diacr = value;
769 return;
770 }
771
772 put_queue(value);
773 }
774
775 #define A_GRAVE '`'
776 #define A_ACUTE '\''
777 #define A_CFLEX '^'
778 #define A_TILDE '~'
779 #define A_DIAER '"'
780 static unsigned char ret_diacr[] =
781 {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER };
782
783
784
785
786 static void do_dead(unsigned char value, char up_flag)
787 {
788 if (up_flag)
789 return;
790
791 value = ret_diacr[value];
792 if (diacr == value) {
793 diacr = 0;
794 put_queue(value);
795 return;
796 }
797 diacr = value;
798 }
799
800
801
802
803
804 unsigned char handle_diacr(unsigned char ch)
805 {
806 int d = diacr;
807 int i;
808
809 diacr = 0;
810 if (ch == ' ')
811 return d;
812
813 for (i = 0; i < accent_table_size; i++) {
814 if (accent_table[i].diacr == d && accent_table[i].base == ch)
815 return accent_table[i].result;
816 }
817
818 put_queue(d);
819 return ch;
820 }
821
822 static void do_cons(unsigned char value, char up_flag)
823 {
824 if (up_flag)
825 return;
826 want_console = value;
827 }
828
829 static void do_fn(unsigned char value, char up_flag)
830 {
831 if (up_flag)
832 return;
833 if (value < SIZE(func_table)) {
834 if (func_table[value])
835 puts_queue(func_table[value]);
836 } else
837 printk("do_fn called with value=%d\n", value);
838 }
839
840 static void do_pad(unsigned char value, char up_flag)
841 {
842 static char *pad_chars = "0123456789+-*/\015,.?";
843 static char *app_map = "pqrstuvwxylSRQMnn?";
844
845 if (up_flag)
846 return;
847
848
849 if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
850 applkey(app_map[value], 1);
851 return;
852 }
853
854 if (!vc_kbd_led(kbd,VC_NUMLOCK))
855 switch (value) {
856 case KVAL(K_PCOMMA):
857 case KVAL(K_PDOT):
858 do_fn(KVAL(K_REMOVE), 0);
859 return;
860 case KVAL(K_P0):
861 do_fn(KVAL(K_INSERT), 0);
862 return;
863 case KVAL(K_P1):
864 do_fn(KVAL(K_SELECT), 0);
865 return;
866 case KVAL(K_P2):
867 do_cur(KVAL(K_DOWN), 0);
868 return;
869 case KVAL(K_P3):
870 do_fn(KVAL(K_PGDN), 0);
871 return;
872 case KVAL(K_P4):
873 do_cur(KVAL(K_LEFT), 0);
874 return;
875 case KVAL(K_P6):
876 do_cur(KVAL(K_RIGHT), 0);
877 return;
878 case KVAL(K_P7):
879 do_fn(KVAL(K_FIND), 0);
880 return;
881 case KVAL(K_P8):
882 do_cur(KVAL(K_UP), 0);
883 return;
884 case KVAL(K_P9):
885 do_fn(KVAL(K_PGUP), 0);
886 return;
887 case KVAL(K_P5):
888 applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
889 return;
890 }
891
892 put_queue(pad_chars[value]);
893 if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
894 put_queue(10);
895 }
896
897 static void do_cur(unsigned char value, char up_flag)
898 {
899 static char *cur_chars = "BDCA";
900 if (up_flag)
901 return;
902
903 applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
904 }
905
906 static void do_shift(unsigned char value, char up_flag)
907 {
908 int old_state = shift_state;
909
910 if (rep)
911 return;
912
913
914
915 if (value == KVAL(K_CAPSSHIFT)) {
916 value = KVAL(K_SHIFT);
917 if (!up_flag)
918 clr_vc_kbd_led(kbd, VC_CAPSLOCK);
919 }
920
921 if (up_flag) {
922
923
924 if (k_down[value])
925 k_down[value]--;
926 } else
927 k_down[value]++;
928
929 if (k_down[value])
930 shift_state |= (1 << value);
931 else
932 shift_state &= ~ (1 << value);
933
934
935 if (up_flag && shift_state != old_state && npadch != -1) {
936 if (kbd->kbdmode == VC_UNICODE)
937 to_utf8(npadch & 0xffff);
938 else
939 put_queue(npadch & 0xff);
940 npadch = -1;
941 }
942 }
943
944
945
946
947 void compute_shiftstate(void)
948 {
949 int i, j, k, sym, val;
950
951 shift_state = 0;
952 for(i=0; i < SIZE(k_down); i++)
953 k_down[i] = 0;
954
955 for(i=0; i < SIZE(key_down); i++)
956 if(key_down[i]) {
957 k = (i<<5);
958 for(j=0; j<32; j++,k++)
959 if(test_bit(k, key_down)) {
960 sym = U(plain_map[k]);
961 if(KTYP(sym) == KT_SHIFT) {
962 val = KVAL(sym);
963 if (val == KVAL(K_CAPSSHIFT))
964 val = KVAL(K_SHIFT);
965 k_down[val]++;
966 shift_state |= (1<<val);
967 }
968 }
969 }
970 }
971
972 static void do_meta(unsigned char value, char up_flag)
973 {
974 if (up_flag)
975 return;
976
977 if (vc_kbd_mode(kbd, VC_META)) {
978 put_queue('\033');
979 put_queue(value);
980 } else
981 put_queue(value | 0x80);
982 }
983
984 static void do_ascii(unsigned char value, char up_flag)
985 {
986 int base;
987
988 if (up_flag)
989 return;
990
991 if (value < 10)
992 base = 10;
993 else {
994 value -= 10;
995 base = 16;
996 }
997
998 if (npadch == -1)
999 npadch = value;
1000 else
1001 npadch = npadch * base + value;
1002 }
1003
1004 static void do_lock(unsigned char value, char up_flag)
1005 {
1006 if (up_flag || rep)
1007 return;
1008 chg_vc_kbd_lock(kbd, value);
1009 }
1010
1011
1012
1013
1014
1015
1016 static int send_data(unsigned char data)
1017 {
1018 int retries = 3;
1019 int i;
1020
1021 do {
1022 kb_wait();
1023 acknowledge = 0;
1024 resend = 0;
1025 reply_expected = 1;
1026 outb_p(data, 0x60);
1027 for(i=0; i<0x200000; i++) {
1028 inb_p(0x64);
1029 if (acknowledge)
1030 return 1;
1031 if (resend)
1032 break;
1033 }
1034 if (!resend)
1035 return 0;
1036 } while (retries-- > 0);
1037 return 0;
1038 }
1039
1040
1041
1042
1043
1044
1045
1046 static unsigned char ledstate = 0xff;
1047 static unsigned char ledioctl;
1048
1049 unsigned char getledstate(void) {
1050 return ledstate;
1051 }
1052
1053 void setledstate(struct kbd_struct *kbd, unsigned int led) {
1054 if (!(led & ~7)) {
1055 ledioctl = led;
1056 kbd->ledmode = LED_SHOW_IOCTL;
1057 } else
1058 kbd->ledmode = LED_SHOW_FLAGS;
1059 set_leds();
1060 }
1061
1062 static struct ledptr {
1063 unsigned int *addr;
1064 unsigned int mask;
1065 unsigned char valid:1;
1066 } ledptrs[3];
1067
1068 void register_leds(int console, unsigned int led,
1069 unsigned int *addr, unsigned int mask) {
1070 struct kbd_struct *kbd = kbd_table + console;
1071 if (led < 3) {
1072 ledptrs[led].addr = addr;
1073 ledptrs[led].mask = mask;
1074 ledptrs[led].valid = 1;
1075 kbd->ledmode = LED_SHOW_MEM;
1076 } else
1077 kbd->ledmode = LED_SHOW_FLAGS;
1078 }
1079
1080 static inline unsigned char getleds(void){
1081 struct kbd_struct *kbd = kbd_table + fg_console;
1082 unsigned char leds;
1083
1084 if (kbd->ledmode == LED_SHOW_IOCTL)
1085 return ledioctl;
1086 leds = kbd->ledflagstate;
1087 if (kbd->ledmode == LED_SHOW_MEM) {
1088 if (ledptrs[0].valid) {
1089 if (*ledptrs[0].addr & ledptrs[0].mask)
1090 leds |= 1;
1091 else
1092 leds &= ~1;
1093 }
1094 if (ledptrs[1].valid) {
1095 if (*ledptrs[1].addr & ledptrs[1].mask)
1096 leds |= 2;
1097 else
1098 leds &= ~2;
1099 }
1100 if (ledptrs[2].valid) {
1101 if (*ledptrs[2].addr & ledptrs[2].mask)
1102 leds |= 4;
1103 else
1104 leds &= ~4;
1105 }
1106 }
1107 return leds;
1108 }
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123 static void kbd_bh(void * unused)
1124 {
1125 unsigned char leds = getleds();
1126
1127 if (leds != ledstate) {
1128 ledstate = leds;
1129 if (!send_data(0xed) || !send_data(leds))
1130 send_data(0xf4);
1131 }
1132 if (want_console >= 0) {
1133 if (want_console != fg_console) {
1134 change_console(want_console);
1135
1136
1137
1138 }
1139 want_console = -1;
1140 }
1141 poke_blanked_console();
1142 cli();
1143 if ((inb_p(0x64) & kbd_read_mask) == 0x01)
1144 fake_keyboard_interrupt();
1145 sti();
1146 }
1147
1148 unsigned long kbd_init(unsigned long kmem_start)
1149 {
1150 int i;
1151 struct kbd_struct kbd0;
1152 extern struct tty_driver console_driver;
1153
1154 kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
1155 kbd0.ledmode = LED_SHOW_FLAGS;
1156 kbd0.lockstate = KBD_DEFLOCK;
1157 kbd0.modeflags = KBD_DEFMODE;
1158 kbd0.kbdmode = VC_XLATE;
1159
1160 for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
1161 kbd_table[i] = kbd0;
1162
1163 ttytab = console_driver.table;
1164
1165 bh_base[KEYBOARD_BH].routine = kbd_bh;
1166 request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard");
1167 #ifdef __alpha__
1168
1169 kb_wait();
1170 outb(0x60,0x64);
1171 kb_wait();
1172 outb(0x41,0x60);
1173 kb_wait();
1174 if (!send_data(0xf0) || !send_data(0x02))
1175 printk("Scanmode 2 change failed\n");
1176 #endif
1177 mark_bh(KEYBOARD_BH);
1178 enable_bh(KEYBOARD_BH);
1179 return kmem_start;
1180 }