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