This source file includes following definitions.
- kb_wait
- send_cmd
- to_utf8
- setkeycode
- getkeycode
- keyboard_interrupt
- put_queue
- puts_queue
- applkey
- enter
- caps_toggle
- caps_on
- show_ptregs
- hold
- num
- bare_num
- lastcons
- decr_console
- incr_console
- send_intr
- scroll_forw
- scroll_back
- boot_it
- compose
- spawn_console
- SAK
- do_ignore
- do_null
- do_spec
- do_lowercase
- do_self
- do_dead
- handle_diacr
- do_cons
- do_fn
- do_pad
- do_cur
- do_shift
- compute_shiftstate
- do_meta
- do_ascii
- do_lock
- do_slock
- send_data
- getledstate
- setledstate
- register_leds
- getleds
- kbd_bh
- kbd_init
- kbd_wait_for_input
- kbd_write
- alpha_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 add_keyboard_randomness(scancode);
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 ^ kbd->slockstate;
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 if (type != KT_SLOCK)
552 kbd->slockstate = 0;
553 } else {
554
555 if (!up_flag)
556 to_utf8(keysym);
557 }
558 } else {
559
560
561 #if 1
562 compute_shiftstate();
563 #else
564 keysym = U(plain_map[keycode]);
565 type = KTYP(keysym);
566 if (type == KT_SHIFT)
567 (*key_handler[type])(keysym & 0xff, up_flag);
568 #endif
569 }
570 }
571
572 end_kbd_intr:
573 send_cmd(0xAE);
574 }
575
576 static void put_queue(int ch)
577 {
578 wake_up(&keypress_wait);
579 if (tty) {
580 tty_insert_flip_char(tty, ch, 0);
581 tty_schedule_flip(tty);
582 }
583 }
584
585 static void puts_queue(char *cp)
586 {
587 wake_up(&keypress_wait);
588 if (!tty)
589 return;
590
591 while (*cp) {
592 tty_insert_flip_char(tty, *cp, 0);
593 cp++;
594 }
595 tty_schedule_flip(tty);
596 }
597
598 static void applkey(int key, char mode)
599 {
600 static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
601
602 buf[1] = (mode ? 'O' : '[');
603 buf[2] = key;
604 puts_queue(buf);
605 }
606
607 static void enter(void)
608 {
609 put_queue(13);
610 if (vc_kbd_mode(kbd,VC_CRLF))
611 put_queue(10);
612 }
613
614 static void caps_toggle(void)
615 {
616 if (rep)
617 return;
618 chg_vc_kbd_led(kbd, VC_CAPSLOCK);
619 }
620
621 static void caps_on(void)
622 {
623 if (rep)
624 return;
625 set_vc_kbd_led(kbd, VC_CAPSLOCK);
626 }
627
628 static void show_ptregs(void)
629 {
630 if (pt_regs)
631 show_regs(pt_regs);
632 }
633
634 static void hold(void)
635 {
636 if (rep || !tty)
637 return;
638
639
640
641
642
643
644 if (tty->stopped)
645 start_tty(tty);
646 else
647 stop_tty(tty);
648 }
649
650 static void num(void)
651 {
652 if (vc_kbd_mode(kbd,VC_APPLIC))
653 applkey('P', 1);
654 else
655 bare_num();
656 }
657
658
659
660
661
662
663
664 static void bare_num(void)
665 {
666 if (!rep)
667 chg_vc_kbd_led(kbd,VC_NUMLOCK);
668 }
669
670 static void lastcons(void)
671 {
672
673 want_console = last_console;
674 }
675
676 static void decr_console(void)
677 {
678 int i;
679
680 for (i = fg_console-1; i != fg_console; i--) {
681 if (i == -1)
682 i = MAX_NR_CONSOLES-1;
683 if (vc_cons_allocated(i))
684 break;
685 }
686 want_console = i;
687 }
688
689 static void incr_console(void)
690 {
691 int i;
692
693 for (i = fg_console+1; i != fg_console; i++) {
694 if (i == MAX_NR_CONSOLES)
695 i = 0;
696 if (vc_cons_allocated(i))
697 break;
698 }
699 want_console = i;
700 }
701
702 static void send_intr(void)
703 {
704 if (!tty)
705 return;
706 tty_insert_flip_char(tty, 0, TTY_BREAK);
707 tty_schedule_flip(tty);
708 }
709
710 static void scroll_forw(void)
711 {
712 scrollfront(0);
713 }
714
715 static void scroll_back(void)
716 {
717 scrollback(0);
718 }
719
720 static void boot_it(void)
721 {
722 ctrl_alt_del();
723 }
724
725 static void compose(void)
726 {
727 dead_key_next = 1;
728 }
729
730 int spawnpid, spawnsig;
731
732 static void spawn_console(void)
733 {
734 if (spawnpid)
735 if(kill_proc(spawnpid, spawnsig, 1))
736 spawnpid = 0;
737 }
738
739 static void SAK(void)
740 {
741 do_SAK(tty);
742 #if 0
743
744
745
746
747
748
749
750
751
752 reset_vc(fg_console);
753 do_unblank_screen();
754 #endif
755 }
756
757 static void do_ignore(unsigned char value, char up_flag)
758 {
759 }
760
761 static void do_null()
762 {
763 compute_shiftstate();
764 }
765
766 static void do_spec(unsigned char value, char up_flag)
767 {
768 if (up_flag)
769 return;
770 if (value >= SIZE(spec_fn_table))
771 return;
772 spec_fn_table[value]();
773 }
774
775 static void do_lowercase(unsigned char value, char up_flag)
776 {
777 printk("keyboard.c: do_lowercase was called - impossible\n");
778 }
779
780 static void do_self(unsigned char value, char up_flag)
781 {
782 if (up_flag)
783 return;
784
785 if (diacr)
786 value = handle_diacr(value);
787
788 if (dead_key_next) {
789 dead_key_next = 0;
790 diacr = value;
791 return;
792 }
793
794 put_queue(value);
795 }
796
797 #define A_GRAVE '`'
798 #define A_ACUTE '\''
799 #define A_CFLEX '^'
800 #define A_TILDE '~'
801 #define A_DIAER '"'
802 static unsigned char ret_diacr[] =
803 {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER };
804
805
806
807
808 static void do_dead(unsigned char value, char up_flag)
809 {
810 if (up_flag)
811 return;
812
813 value = ret_diacr[value];
814 if (diacr == value) {
815 diacr = 0;
816 put_queue(value);
817 return;
818 }
819 diacr = value;
820 }
821
822
823
824
825
826 unsigned char handle_diacr(unsigned char ch)
827 {
828 int d = diacr;
829 int i;
830
831 diacr = 0;
832 if (ch == ' ')
833 return d;
834
835 for (i = 0; i < accent_table_size; i++) {
836 if (accent_table[i].diacr == d && accent_table[i].base == ch)
837 return accent_table[i].result;
838 }
839
840 put_queue(d);
841 return ch;
842 }
843
844 static void do_cons(unsigned char value, char up_flag)
845 {
846 if (up_flag)
847 return;
848 want_console = value;
849 }
850
851 static void do_fn(unsigned char value, char up_flag)
852 {
853 if (up_flag)
854 return;
855 if (value < SIZE(func_table)) {
856 if (func_table[value])
857 puts_queue(func_table[value]);
858 } else
859 printk("do_fn called with value=%d\n", value);
860 }
861
862 static void do_pad(unsigned char value, char up_flag)
863 {
864 static const char *pad_chars = "0123456789+-*/\015,.?";
865 static const char *app_map = "pqrstuvwxylSRQMnn?";
866
867 if (up_flag)
868 return;
869
870
871 if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
872 applkey(app_map[value], 1);
873 return;
874 }
875
876 if (!vc_kbd_led(kbd,VC_NUMLOCK))
877 switch (value) {
878 case KVAL(K_PCOMMA):
879 case KVAL(K_PDOT):
880 do_fn(KVAL(K_REMOVE), 0);
881 return;
882 case KVAL(K_P0):
883 do_fn(KVAL(K_INSERT), 0);
884 return;
885 case KVAL(K_P1):
886 do_fn(KVAL(K_SELECT), 0);
887 return;
888 case KVAL(K_P2):
889 do_cur(KVAL(K_DOWN), 0);
890 return;
891 case KVAL(K_P3):
892 do_fn(KVAL(K_PGDN), 0);
893 return;
894 case KVAL(K_P4):
895 do_cur(KVAL(K_LEFT), 0);
896 return;
897 case KVAL(K_P6):
898 do_cur(KVAL(K_RIGHT), 0);
899 return;
900 case KVAL(K_P7):
901 do_fn(KVAL(K_FIND), 0);
902 return;
903 case KVAL(K_P8):
904 do_cur(KVAL(K_UP), 0);
905 return;
906 case KVAL(K_P9):
907 do_fn(KVAL(K_PGUP), 0);
908 return;
909 case KVAL(K_P5):
910 applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
911 return;
912 }
913
914 put_queue(pad_chars[value]);
915 if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
916 put_queue(10);
917 }
918
919 static void do_cur(unsigned char value, char up_flag)
920 {
921 static const char *cur_chars = "BDCA";
922 if (up_flag)
923 return;
924
925 applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
926 }
927
928 static void do_shift(unsigned char value, char up_flag)
929 {
930 int old_state = shift_state;
931
932 if (rep)
933 return;
934
935
936
937 if (value == KVAL(K_CAPSSHIFT)) {
938 value = KVAL(K_SHIFT);
939 if (!up_flag)
940 clr_vc_kbd_led(kbd, VC_CAPSLOCK);
941 }
942
943 if (up_flag) {
944
945
946 if (k_down[value])
947 k_down[value]--;
948 } else
949 k_down[value]++;
950
951 if (k_down[value])
952 shift_state |= (1 << value);
953 else
954 shift_state &= ~ (1 << value);
955
956
957 if (up_flag && shift_state != old_state && npadch != -1) {
958 if (kbd->kbdmode == VC_UNICODE)
959 to_utf8(npadch & 0xffff);
960 else
961 put_queue(npadch & 0xff);
962 npadch = -1;
963 }
964 }
965
966
967
968
969 void compute_shiftstate(void)
970 {
971 int i, j, k, sym, val;
972
973 shift_state = 0;
974 for(i=0; i < SIZE(k_down); i++)
975 k_down[i] = 0;
976
977 for(i=0; i < SIZE(key_down); i++)
978 if(key_down[i]) {
979 k = i*BITS_PER_LONG;
980 for(j=0; j<BITS_PER_LONG; j++,k++)
981 if(test_bit(k, key_down)) {
982 sym = U(plain_map[k]);
983 if(KTYP(sym) == KT_SHIFT) {
984 val = KVAL(sym);
985 if (val == KVAL(K_CAPSSHIFT))
986 val = KVAL(K_SHIFT);
987 k_down[val]++;
988 shift_state |= (1<<val);
989 }
990 }
991 }
992 }
993
994 static void do_meta(unsigned char value, char up_flag)
995 {
996 if (up_flag)
997 return;
998
999 if (vc_kbd_mode(kbd, VC_META)) {
1000 put_queue('\033');
1001 put_queue(value);
1002 } else
1003 put_queue(value | 0x80);
1004 }
1005
1006 static void do_ascii(unsigned char value, char up_flag)
1007 {
1008 int base;
1009
1010 if (up_flag)
1011 return;
1012
1013 if (value < 10)
1014 base = 10;
1015 else {
1016 value -= 10;
1017 base = 16;
1018 }
1019
1020 if (npadch == -1)
1021 npadch = value;
1022 else
1023 npadch = npadch * base + value;
1024 }
1025
1026 static void do_lock(unsigned char value, char up_flag)
1027 {
1028 if (up_flag || rep)
1029 return;
1030 chg_vc_kbd_lock(kbd, value);
1031 }
1032
1033 static void do_slock(unsigned char value, char up_flag)
1034 {
1035 if (up_flag || rep)
1036 return;
1037 chg_vc_kbd_slock(kbd, value);
1038 }
1039
1040
1041
1042
1043
1044
1045 static int send_data(unsigned char data)
1046 {
1047 int retries = 3;
1048 int i;
1049
1050 do {
1051 kb_wait();
1052 acknowledge = 0;
1053 resend = 0;
1054 reply_expected = 1;
1055 outb_p(data, 0x60);
1056 for(i=0; i<0x200000; i++) {
1057 inb_p(0x64);
1058 if (acknowledge)
1059 return 1;
1060 if (resend)
1061 break;
1062 }
1063 if (!resend)
1064 return 0;
1065 } while (retries-- > 0);
1066 return 0;
1067 }
1068
1069
1070
1071
1072
1073
1074
1075 static unsigned char ledstate = 0xff;
1076 static unsigned char ledioctl;
1077
1078 unsigned char getledstate(void) {
1079 return ledstate;
1080 }
1081
1082 void setledstate(struct kbd_struct *kbd, unsigned int led) {
1083 if (!(led & ~7)) {
1084 ledioctl = led;
1085 kbd->ledmode = LED_SHOW_IOCTL;
1086 } else
1087 kbd->ledmode = LED_SHOW_FLAGS;
1088 set_leds();
1089 }
1090
1091 static struct ledptr {
1092 unsigned int *addr;
1093 unsigned int mask;
1094 unsigned char valid:1;
1095 } ledptrs[3];
1096
1097 void register_leds(int console, unsigned int led,
1098 unsigned int *addr, unsigned int mask) {
1099 struct kbd_struct *kbd = kbd_table + console;
1100 if (led < 3) {
1101 ledptrs[led].addr = addr;
1102 ledptrs[led].mask = mask;
1103 ledptrs[led].valid = 1;
1104 kbd->ledmode = LED_SHOW_MEM;
1105 } else
1106 kbd->ledmode = LED_SHOW_FLAGS;
1107 }
1108
1109 static inline unsigned char getleds(void){
1110 struct kbd_struct *kbd = kbd_table + fg_console;
1111 unsigned char leds;
1112
1113 if (kbd->ledmode == LED_SHOW_IOCTL)
1114 return ledioctl;
1115 leds = kbd->ledflagstate;
1116 if (kbd->ledmode == LED_SHOW_MEM) {
1117 if (ledptrs[0].valid) {
1118 if (*ledptrs[0].addr & ledptrs[0].mask)
1119 leds |= 1;
1120 else
1121 leds &= ~1;
1122 }
1123 if (ledptrs[1].valid) {
1124 if (*ledptrs[1].addr & ledptrs[1].mask)
1125 leds |= 2;
1126 else
1127 leds &= ~2;
1128 }
1129 if (ledptrs[2].valid) {
1130 if (*ledptrs[2].addr & ledptrs[2].mask)
1131 leds |= 4;
1132 else
1133 leds &= ~4;
1134 }
1135 }
1136 return leds;
1137 }
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152 static void kbd_bh(void * unused)
1153 {
1154 unsigned char leds = getleds();
1155
1156 if (leds != ledstate) {
1157 ledstate = leds;
1158 if (!send_data(0xed) || !send_data(leds))
1159 send_data(0xf4);
1160 }
1161 if (want_console >= 0) {
1162 if (want_console != fg_console) {
1163 change_console(want_console);
1164
1165
1166
1167 }
1168 want_console = -1;
1169 }
1170 poke_blanked_console();
1171 cli();
1172 if ((inb_p(0x64) & kbd_read_mask) == 0x01)
1173 fake_keyboard_interrupt();
1174 sti();
1175 }
1176
1177 int kbd_init(void)
1178 {
1179 int i;
1180 struct kbd_struct kbd0;
1181 extern struct tty_driver console_driver;
1182
1183 kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
1184 kbd0.ledmode = LED_SHOW_FLAGS;
1185 kbd0.lockstate = KBD_DEFLOCK;
1186 kbd0.slockstate = 0;
1187 kbd0.modeflags = KBD_DEFMODE;
1188 kbd0.kbdmode = VC_XLATE;
1189
1190 for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
1191 kbd_table[i] = kbd0;
1192
1193 ttytab = console_driver.table;
1194
1195 bh_base[KEYBOARD_BH].routine = kbd_bh;
1196 request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard");
1197 request_region(0x60,16,"kbd");
1198 #ifdef __alpha__
1199 #if 0
1200
1201 if (inb(0x64) & 0x01) {
1202 inb(0x60);
1203 }
1204
1205
1206 kb_wait();
1207 outb(0x60,0x64);
1208 kb_wait();
1209 outb(0x65,0x60);
1210 kb_wait();
1211 if (!send_data(0xf0) || !send_data(0x02))
1212 printk("Scanmode 2 change failed\n");
1213 #else
1214 {
1215 static int alpha_kbd_init(void);
1216
1217 alpha_kbd_init();
1218 }
1219 #endif
1220 #endif
1221 mark_bh(KEYBOARD_BH);
1222 enable_bh(KEYBOARD_BH);
1223 return 0;
1224 }
1225
1226 #ifdef __alpha__
1227
1228
1229
1230 #define KBD_STATUS_REG (unsigned int) 0x64
1231 #define KBD_CNTL_REG (unsigned int) 0x64
1232 #define KBD_DATA_REG (unsigned int) 0x60
1233
1234
1235
1236 #define KBD_READ_MODE (unsigned int) 0x20
1237 #define KBD_WRITE_MODE (unsigned int) 0x60
1238 #define KBD_SELF_TEST (unsigned int) 0xAA
1239 #define KBD_SELF_TEST2 (unsigned int) 0xAB
1240 #define KBD_CNTL_ENABLE (unsigned int) 0xAE
1241
1242
1243
1244 #define KBD_ENABLE (unsigned int) 0xF4
1245 #define KBD_DISABLE (unsigned int) 0xF5
1246 #define KBD_RESET (unsigned int) 0xFF
1247
1248
1249
1250 #define KBD_ACK (unsigned int) 0xFA
1251 #define KBD_POR (unsigned int) 0xAA
1252
1253
1254
1255 #define KBD_OBF (unsigned int) 0x01
1256 #define KBD_IBF (unsigned int) 0x02
1257 #define KBD_GTO (unsigned int) 0x40
1258 #define KBD_PERR (unsigned int) 0x80
1259
1260
1261
1262 #define KBD_EKI (unsigned int) 0x01
1263
1264 #define TIMEOUT_CONST 500000
1265
1266 static int
1267 kbd_wait_for_input(void)
1268 {
1269 int n;
1270 int status, data;
1271
1272 n = TIMEOUT_CONST;
1273 do {
1274 status = inb(KBD_STATUS_REG);
1275
1276
1277
1278
1279
1280
1281 if (!(status & KBD_OBF))
1282 continue;
1283
1284 data = inb(KBD_DATA_REG);
1285
1286
1287
1288
1289
1290
1291
1292 if (status & (KBD_GTO | KBD_PERR)) {
1293 continue;
1294 }
1295 return (data & 0xff);
1296 } while (--n);
1297 return (-1);
1298 }
1299
1300 static void
1301 kbd_write(int address, int data)
1302 {
1303 int status;
1304
1305 do {
1306 status = inb(KBD_STATUS_REG);
1307 } while (status & KBD_IBF);
1308 outb(data, address);
1309 }
1310
1311 static int
1312 alpha_kbd_init(void)
1313 {
1314 unsigned long flags;
1315
1316 save_flags(flags); cli();
1317
1318
1319 while (kbd_wait_for_input() != -1)
1320 continue;
1321
1322
1323
1324
1325
1326
1327 kbd_write(KBD_CNTL_REG, KBD_SELF_TEST);
1328 if (kbd_wait_for_input() != 0x55) {
1329 printk("alpha_kbd_init: keyboard failed self test.\n");
1330 restore_flags(flags);
1331 return(-1);
1332 }
1333
1334
1335
1336
1337
1338
1339 kbd_write(KBD_CNTL_REG, KBD_SELF_TEST2);
1340 if (kbd_wait_for_input() != 0x00) {
1341 printk("alpha_kbd_init: keyboard failed self test 2.\n");
1342 restore_flags(flags);
1343 return(-1);
1344 }
1345
1346
1347 kbd_write(KBD_CNTL_REG, KBD_CNTL_ENABLE);
1348
1349
1350
1351
1352
1353
1354
1355 kbd_write(KBD_DATA_REG, KBD_RESET);
1356 if (kbd_wait_for_input() != KBD_ACK) {
1357 printk("alpha_kbd_init: reset kbd failed, no ACK.\n");
1358 restore_flags(flags);
1359 return(-1);
1360 }
1361
1362 if (kbd_wait_for_input() != KBD_POR) {
1363 printk("alpha_kbd_init: reset kbd failed, not POR.\n");
1364 restore_flags(flags);
1365 return(-1);
1366 }
1367
1368
1369
1370
1371 kbd_write(KBD_DATA_REG, KBD_DISABLE);
1372 if (kbd_wait_for_input() != KBD_ACK) {
1373 printk("alpha_kbd_init: disable kbd failed, no ACK.\n");
1374 restore_flags(flags);
1375 return(-1);
1376 }
1377
1378
1379
1380
1381
1382
1383 kbd_write(KBD_CNTL_REG, KBD_WRITE_MODE);
1384 kbd_write(KBD_DATA_REG, KBD_EKI);
1385
1386
1387
1388
1389 kbd_write(KBD_DATA_REG, KBD_ENABLE);
1390 if (kbd_wait_for_input() != KBD_ACK) {
1391 printk("alpha_kbd_init: keyboard enable failed.\n");
1392 restore_flags(flags);
1393 return(-1);
1394 }
1395
1396 restore_flags(flags);
1397
1398 return (1);
1399
1400 }
1401 #endif