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