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