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