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