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