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