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