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