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