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, void *dev_id, 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 mark_bh(CONSOLE_BH);
380 add_keyboard_randomness(scancode);
381
382 tty = ttytab[fg_console];
383 kbd = kbd_table + fg_console;
384 if ((raw_mode = (kbd->kbdmode == VC_RAW))) {
385 put_queue(scancode);
386
387
388
389 }
390
391 if (scancode == 0xff) {
392
393
394 #ifndef KBD_IS_FOCUS_9000
395 #ifdef KBD_REPORT_ERR
396 if (!raw_mode)
397 printk("keyboard error\n");
398 #endif
399 #endif
400 prev_scancode = 0;
401 goto end_kbd_intr;
402 }
403
404 if (scancode == 0xe0 || scancode == 0xe1) {
405 prev_scancode = scancode;
406 goto end_kbd_intr;
407 }
408
409
410
411
412 up_flag = (scancode & 0200);
413 scancode &= 0x7f;
414
415 if (prev_scancode) {
416
417
418
419
420 if (prev_scancode != 0xe0) {
421 if (prev_scancode == 0xe1 && scancode == 0x1d) {
422 prev_scancode = 0x100;
423 goto end_kbd_intr;
424 } else if (prev_scancode == 0x100 && scancode == 0x45) {
425 keycode = E1_PAUSE;
426 prev_scancode = 0;
427 } else {
428 #ifdef KBD_REPORT_UNKN
429 if (!raw_mode)
430 printk("keyboard: unknown e1 escape sequence\n");
431 #endif
432 prev_scancode = 0;
433 goto end_kbd_intr;
434 }
435 } else {
436 prev_scancode = 0;
437
438
439
440
441
442
443
444
445
446
447
448
449
450 if (scancode == 0x2a || scancode == 0x36)
451 goto end_kbd_intr;
452
453 if (e0_keys[scancode])
454 keycode = e0_keys[scancode];
455 else {
456 #ifdef KBD_REPORT_UNKN
457 if (!raw_mode)
458 printk("keyboard: unknown scancode e0 %02x\n", scancode);
459 #endif
460 goto end_kbd_intr;
461 }
462 }
463 } else if (scancode >= SC_LIM) {
464
465
466
467
468
469
470
471
472
473
474 keycode = high_keys[scancode - SC_LIM];
475
476 if (!keycode) {
477 if (!raw_mode) {
478 #ifdef KBD_REPORT_UNKN
479 printk("keyboard: unrecognized scancode (%02x) - ignored\n"
480 , scancode);
481 #endif
482 }
483 goto end_kbd_intr;
484 }
485 } else
486 keycode = scancode;
487
488
489
490
491
492
493
494
495 if (up_flag) {
496 rep = 0;
497 if(!clear_bit(keycode, key_down)) {
498
499
500
501
502 if (keycode >= SC_LIM || keycode == 85)
503 up_flag = 0;
504 }
505 } else
506 rep = set_bit(keycode, key_down);
507
508 if (raw_mode)
509 goto end_kbd_intr;
510
511 if (kbd->kbdmode == VC_MEDIUMRAW) {
512
513 put_queue(keycode + up_flag);
514 goto end_kbd_intr;
515 }
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530 if (!rep ||
531 (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
532 (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
533 u_short keysym;
534 u_char type;
535
536
537 int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate;
538 ushort *key_map = key_maps[shift_final];
539
540 if (key_map != NULL) {
541 keysym = key_map[keycode];
542 type = KTYP(keysym);
543
544 if (type >= 0xf0) {
545 type -= 0xf0;
546 if (type == KT_LETTER) {
547 type = KT_LATIN;
548 if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
549 key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
550 if (key_map)
551 keysym = key_map[keycode];
552 }
553 }
554 (*key_handler[type])(keysym & 0xff, up_flag);
555 if (type != KT_SLOCK)
556 kbd->slockstate = 0;
557 } else {
558
559 if (!up_flag)
560 to_utf8(keysym);
561 }
562 } else {
563
564
565 #if 1
566 compute_shiftstate();
567 #else
568 keysym = U(plain_map[keycode]);
569 type = KTYP(keysym);
570 if (type == KT_SHIFT)
571 (*key_handler[type])(keysym & 0xff, up_flag);
572 #endif
573 }
574 }
575
576 end_kbd_intr:
577 send_cmd(0xAE);
578 }
579
580 static void put_queue(int ch)
581 {
582 wake_up(&keypress_wait);
583 if (tty) {
584 tty_insert_flip_char(tty, ch, 0);
585 tty_schedule_flip(tty);
586 }
587 }
588
589 static void puts_queue(char *cp)
590 {
591 wake_up(&keypress_wait);
592 if (!tty)
593 return;
594
595 while (*cp) {
596 tty_insert_flip_char(tty, *cp, 0);
597 cp++;
598 }
599 tty_schedule_flip(tty);
600 }
601
602 static void applkey(int key, char mode)
603 {
604 static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
605
606 buf[1] = (mode ? 'O' : '[');
607 buf[2] = key;
608 puts_queue(buf);
609 }
610
611 static void enter(void)
612 {
613 put_queue(13);
614 if (vc_kbd_mode(kbd,VC_CRLF))
615 put_queue(10);
616 }
617
618 static void caps_toggle(void)
619 {
620 if (rep)
621 return;
622 chg_vc_kbd_led(kbd, VC_CAPSLOCK);
623 }
624
625 static void caps_on(void)
626 {
627 if (rep)
628 return;
629 set_vc_kbd_led(kbd, VC_CAPSLOCK);
630 }
631
632 static void show_ptregs(void)
633 {
634 if (pt_regs)
635 show_regs(pt_regs);
636 }
637
638 static void hold(void)
639 {
640 if (rep || !tty)
641 return;
642
643
644
645
646
647
648 if (tty->stopped)
649 start_tty(tty);
650 else
651 stop_tty(tty);
652 }
653
654 static void num(void)
655 {
656 if (vc_kbd_mode(kbd,VC_APPLIC))
657 applkey('P', 1);
658 else
659 bare_num();
660 }
661
662
663
664
665
666
667
668 static void bare_num(void)
669 {
670 if (!rep)
671 chg_vc_kbd_led(kbd,VC_NUMLOCK);
672 }
673
674 static void lastcons(void)
675 {
676
677 set_console(last_console);
678 }
679
680 static void decr_console(void)
681 {
682 int i;
683
684 for (i = fg_console-1; i != fg_console; i--) {
685 if (i == -1)
686 i = MAX_NR_CONSOLES-1;
687 if (vc_cons_allocated(i))
688 break;
689 }
690 set_console(i);
691 }
692
693 static void incr_console(void)
694 {
695 int i;
696
697 for (i = fg_console+1; i != fg_console; i++) {
698 if (i == MAX_NR_CONSOLES)
699 i = 0;
700 if (vc_cons_allocated(i))
701 break;
702 }
703 set_console(i);
704 }
705
706 static void send_intr(void)
707 {
708 if (!tty)
709 return;
710 tty_insert_flip_char(tty, 0, TTY_BREAK);
711 tty_schedule_flip(tty);
712 }
713
714 static void scroll_forw(void)
715 {
716 scrollfront(0);
717 }
718
719 static void scroll_back(void)
720 {
721 scrollback(0);
722 }
723
724 static void boot_it(void)
725 {
726 ctrl_alt_del();
727 }
728
729 static void compose(void)
730 {
731 dead_key_next = 1;
732 }
733
734 int spawnpid, spawnsig;
735
736 static void spawn_console(void)
737 {
738 if (spawnpid)
739 if(kill_proc(spawnpid, spawnsig, 1))
740 spawnpid = 0;
741 }
742
743 static void SAK(void)
744 {
745 do_SAK(tty);
746 #if 0
747
748
749
750
751
752
753
754
755
756 reset_vc(fg_console);
757 do_unblank_screen();
758 #endif
759 }
760
761 static void do_ignore(unsigned char value, char up_flag)
762 {
763 }
764
765 static void do_null()
766 {
767 compute_shiftstate();
768 }
769
770 static void do_spec(unsigned char value, char up_flag)
771 {
772 if (up_flag)
773 return;
774 if (value >= SIZE(spec_fn_table))
775 return;
776 spec_fn_table[value]();
777 }
778
779 static void do_lowercase(unsigned char value, char up_flag)
780 {
781 printk("keyboard.c: do_lowercase was called - impossible\n");
782 }
783
784 static void do_self(unsigned char value, char up_flag)
785 {
786 if (up_flag)
787 return;
788
789 if (diacr)
790 value = handle_diacr(value);
791
792 if (dead_key_next) {
793 dead_key_next = 0;
794 diacr = value;
795 return;
796 }
797
798 put_queue(value);
799 }
800
801 #define A_GRAVE '`'
802 #define A_ACUTE '\''
803 #define A_CFLEX '^'
804 #define A_TILDE '~'
805 #define A_DIAER '"'
806 static unsigned char ret_diacr[] =
807 {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER };
808
809
810
811
812 static void do_dead(unsigned char value, char up_flag)
813 {
814 if (up_flag)
815 return;
816
817 value = ret_diacr[value];
818 if (diacr == value) {
819 diacr = 0;
820 put_queue(value);
821 return;
822 }
823 diacr = value;
824 }
825
826
827
828
829
830 unsigned char handle_diacr(unsigned char ch)
831 {
832 int d = diacr;
833 int i;
834
835 diacr = 0;
836 if (ch == ' ')
837 return d;
838
839 for (i = 0; i < accent_table_size; i++) {
840 if (accent_table[i].diacr == d && accent_table[i].base == ch)
841 return accent_table[i].result;
842 }
843
844 put_queue(d);
845 return ch;
846 }
847
848 static void do_cons(unsigned char value, char up_flag)
849 {
850 if (up_flag)
851 return;
852 set_console(value);
853 }
854
855 static void do_fn(unsigned char value, char up_flag)
856 {
857 if (up_flag)
858 return;
859 if (value < SIZE(func_table)) {
860 if (func_table[value])
861 puts_queue(func_table[value]);
862 } else
863 printk("do_fn called with value=%d\n", value);
864 }
865
866 static void do_pad(unsigned char value, char up_flag)
867 {
868 static const char *pad_chars = "0123456789+-*/\015,.?";
869 static const char *app_map = "pqrstuvwxylSRQMnn?";
870
871 if (up_flag)
872 return;
873
874
875 if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
876 applkey(app_map[value], 1);
877 return;
878 }
879
880 if (!vc_kbd_led(kbd,VC_NUMLOCK))
881 switch (value) {
882 case KVAL(K_PCOMMA):
883 case KVAL(K_PDOT):
884 do_fn(KVAL(K_REMOVE), 0);
885 return;
886 case KVAL(K_P0):
887 do_fn(KVAL(K_INSERT), 0);
888 return;
889 case KVAL(K_P1):
890 do_fn(KVAL(K_SELECT), 0);
891 return;
892 case KVAL(K_P2):
893 do_cur(KVAL(K_DOWN), 0);
894 return;
895 case KVAL(K_P3):
896 do_fn(KVAL(K_PGDN), 0);
897 return;
898 case KVAL(K_P4):
899 do_cur(KVAL(K_LEFT), 0);
900 return;
901 case KVAL(K_P6):
902 do_cur(KVAL(K_RIGHT), 0);
903 return;
904 case KVAL(K_P7):
905 do_fn(KVAL(K_FIND), 0);
906 return;
907 case KVAL(K_P8):
908 do_cur(KVAL(K_UP), 0);
909 return;
910 case KVAL(K_P9):
911 do_fn(KVAL(K_PGUP), 0);
912 return;
913 case KVAL(K_P5):
914 applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
915 return;
916 }
917
918 put_queue(pad_chars[value]);
919 if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
920 put_queue(10);
921 }
922
923 static void do_cur(unsigned char value, char up_flag)
924 {
925 static const char *cur_chars = "BDCA";
926 if (up_flag)
927 return;
928
929 applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
930 }
931
932 static void do_shift(unsigned char value, char up_flag)
933 {
934 int old_state = shift_state;
935
936 if (rep)
937 return;
938
939
940
941 if (value == KVAL(K_CAPSSHIFT)) {
942 value = KVAL(K_SHIFT);
943 if (!up_flag)
944 clr_vc_kbd_led(kbd, VC_CAPSLOCK);
945 }
946
947 if (up_flag) {
948
949
950 if (k_down[value])
951 k_down[value]--;
952 } else
953 k_down[value]++;
954
955 if (k_down[value])
956 shift_state |= (1 << value);
957 else
958 shift_state &= ~ (1 << value);
959
960
961 if (up_flag && shift_state != old_state && npadch != -1) {
962 if (kbd->kbdmode == VC_UNICODE)
963 to_utf8(npadch & 0xffff);
964 else
965 put_queue(npadch & 0xff);
966 npadch = -1;
967 }
968 }
969
970
971
972
973 void compute_shiftstate(void)
974 {
975 int i, j, k, sym, val;
976
977 shift_state = 0;
978 for(i=0; i < SIZE(k_down); i++)
979 k_down[i] = 0;
980
981 for(i=0; i < SIZE(key_down); i++)
982 if(key_down[i]) {
983 k = i*BITS_PER_LONG;
984 for(j=0; j<BITS_PER_LONG; j++,k++)
985 if(test_bit(k, key_down)) {
986 sym = U(plain_map[k]);
987 if(KTYP(sym) == KT_SHIFT) {
988 val = KVAL(sym);
989 if (val == KVAL(K_CAPSSHIFT))
990 val = KVAL(K_SHIFT);
991 k_down[val]++;
992 shift_state |= (1<<val);
993 }
994 }
995 }
996 }
997
998 static void do_meta(unsigned char value, char up_flag)
999 {
1000 if (up_flag)
1001 return;
1002
1003 if (vc_kbd_mode(kbd, VC_META)) {
1004 put_queue('\033');
1005 put_queue(value);
1006 } else
1007 put_queue(value | 0x80);
1008 }
1009
1010 static void do_ascii(unsigned char value, char up_flag)
1011 {
1012 int base;
1013
1014 if (up_flag)
1015 return;
1016
1017 if (value < 10)
1018 base = 10;
1019 else {
1020 value -= 10;
1021 base = 16;
1022 }
1023
1024 if (npadch == -1)
1025 npadch = value;
1026 else
1027 npadch = npadch * base + value;
1028 }
1029
1030 static void do_lock(unsigned char value, char up_flag)
1031 {
1032 if (up_flag || rep)
1033 return;
1034 chg_vc_kbd_lock(kbd, value);
1035 }
1036
1037 static void do_slock(unsigned char value, char up_flag)
1038 {
1039 if (up_flag || rep)
1040 return;
1041 chg_vc_kbd_slock(kbd, value);
1042 }
1043
1044
1045
1046
1047
1048
1049 static int send_data(unsigned char data)
1050 {
1051 int retries = 3;
1052 int i;
1053
1054 do {
1055 kb_wait();
1056 acknowledge = 0;
1057 resend = 0;
1058 reply_expected = 1;
1059 outb_p(data, 0x60);
1060 for(i=0; i<0x200000; i++) {
1061 inb_p(0x64);
1062 if (acknowledge)
1063 return 1;
1064 if (resend)
1065 break;
1066 }
1067 if (!resend)
1068 return 0;
1069 } while (retries-- > 0);
1070 return 0;
1071 }
1072
1073
1074
1075
1076
1077
1078
1079 static unsigned char ledstate = 0xff;
1080 static unsigned char ledioctl;
1081
1082 unsigned char getledstate(void) {
1083 return ledstate;
1084 }
1085
1086 void setledstate(struct kbd_struct *kbd, unsigned int led) {
1087 if (!(led & ~7)) {
1088 ledioctl = led;
1089 kbd->ledmode = LED_SHOW_IOCTL;
1090 } else
1091 kbd->ledmode = LED_SHOW_FLAGS;
1092 set_leds();
1093 }
1094
1095 static struct ledptr {
1096 unsigned int *addr;
1097 unsigned int mask;
1098 unsigned char valid:1;
1099 } ledptrs[3];
1100
1101 void register_leds(int console, unsigned int led,
1102 unsigned int *addr, unsigned int mask) {
1103 struct kbd_struct *kbd = kbd_table + console;
1104 if (led < 3) {
1105 ledptrs[led].addr = addr;
1106 ledptrs[led].mask = mask;
1107 ledptrs[led].valid = 1;
1108 kbd->ledmode = LED_SHOW_MEM;
1109 } else
1110 kbd->ledmode = LED_SHOW_FLAGS;
1111 }
1112
1113 static inline unsigned char getleds(void){
1114 struct kbd_struct *kbd = kbd_table + fg_console;
1115 unsigned char leds;
1116
1117 if (kbd->ledmode == LED_SHOW_IOCTL)
1118 return ledioctl;
1119 leds = kbd->ledflagstate;
1120 if (kbd->ledmode == LED_SHOW_MEM) {
1121 if (ledptrs[0].valid) {
1122 if (*ledptrs[0].addr & ledptrs[0].mask)
1123 leds |= 1;
1124 else
1125 leds &= ~1;
1126 }
1127 if (ledptrs[1].valid) {
1128 if (*ledptrs[1].addr & ledptrs[1].mask)
1129 leds |= 2;
1130 else
1131 leds &= ~2;
1132 }
1133 if (ledptrs[2].valid) {
1134 if (*ledptrs[2].addr & ledptrs[2].mask)
1135 leds |= 4;
1136 else
1137 leds &= ~4;
1138 }
1139 }
1140 return leds;
1141 }
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156 static void kbd_bh(void)
1157 {
1158 unsigned char leds = getleds();
1159
1160 if (leds != ledstate) {
1161 ledstate = leds;
1162 if (!send_data(0xed) || !send_data(leds))
1163 send_data(0xf4);
1164 }
1165 }
1166
1167 int kbd_init(void)
1168 {
1169 int i;
1170 struct kbd_struct kbd0;
1171 extern struct tty_driver console_driver;
1172
1173 kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
1174 kbd0.ledmode = LED_SHOW_FLAGS;
1175 kbd0.lockstate = KBD_DEFLOCK;
1176 kbd0.slockstate = 0;
1177 kbd0.modeflags = KBD_DEFMODE;
1178 kbd0.kbdmode = VC_XLATE;
1179
1180 for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
1181 kbd_table[i] = kbd0;
1182
1183 ttytab = console_driver.table;
1184
1185 request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL);
1186 request_region(0x60,16,"kbd");
1187 #ifdef INIT_KBD
1188 initialize_kbd();
1189 #endif
1190 init_bh(KEYBOARD_BH, kbd_bh);
1191 mark_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