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
- 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 static int want_console = -1;
95 static int last_console = 0;
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;
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
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 || (tty->termios && I_IGNBRK(tty)))
692 return;
693 tty_insert_flip_char(tty, 0, TTY_BREAK);
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 static void SAK(void)
717 {
718 do_SAK(tty);
719 #if 0
720
721
722
723
724
725
726
727
728
729 reset_vc(fg_console);
730 unblank_screen();
731 #endif
732 }
733
734 static void do_ignore(unsigned char value, char up_flag)
735 {
736 }
737
738 static void do_null()
739 {
740 compute_shiftstate();
741 }
742
743 static void do_spec(unsigned char value, char up_flag)
744 {
745 if (up_flag)
746 return;
747 if (value >= SIZE(spec_fn_table))
748 return;
749 spec_fn_table[value]();
750 }
751
752 static void do_lowercase(unsigned char value, char up_flag)
753 {
754 printk("keyboard.c: do_lowercase was called - impossible\n");
755 }
756
757 static void do_self(unsigned char value, char up_flag)
758 {
759 if (up_flag)
760 return;
761
762 if (diacr)
763 value = handle_diacr(value);
764
765 if (dead_key_next) {
766 dead_key_next = 0;
767 diacr = value;
768 return;
769 }
770
771 put_queue(value);
772 }
773
774 #define A_GRAVE '`'
775 #define A_ACUTE '\''
776 #define A_CFLEX '^'
777 #define A_TILDE '~'
778 #define A_DIAER '"'
779 static unsigned char ret_diacr[] =
780 {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER };
781
782
783
784
785 static void do_dead(unsigned char value, char up_flag)
786 {
787 if (up_flag)
788 return;
789
790 value = ret_diacr[value];
791 if (diacr == value) {
792 diacr = 0;
793 put_queue(value);
794 return;
795 }
796 diacr = value;
797 }
798
799
800
801
802
803 unsigned char handle_diacr(unsigned char ch)
804 {
805 int d = diacr;
806 int i;
807
808 diacr = 0;
809 if (ch == ' ')
810 return d;
811
812 for (i = 0; i < accent_table_size; i++) {
813 if (accent_table[i].diacr == d && accent_table[i].base == ch)
814 return accent_table[i].result;
815 }
816
817 put_queue(d);
818 return ch;
819 }
820
821 static void do_cons(unsigned char value, char up_flag)
822 {
823 if (up_flag)
824 return;
825 want_console = value;
826 }
827
828 static void do_fn(unsigned char value, char up_flag)
829 {
830 if (up_flag)
831 return;
832 if (value < SIZE(func_table)) {
833 if (func_table[value])
834 puts_queue(func_table[value]);
835 } else
836 printk("do_fn called with value=%d\n", value);
837 }
838
839 static void do_pad(unsigned char value, char up_flag)
840 {
841 static char *pad_chars = "0123456789+-*/\015,.?";
842 static char *app_map = "pqrstuvwxylSRQMnn?";
843
844 if (up_flag)
845 return;
846
847
848 if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
849 applkey(app_map[value], 1);
850 return;
851 }
852
853 if (!vc_kbd_led(kbd,VC_NUMLOCK))
854 switch (value) {
855 case KVAL(K_PCOMMA):
856 case KVAL(K_PDOT):
857 do_fn(KVAL(K_REMOVE), 0);
858 return;
859 case KVAL(K_P0):
860 do_fn(KVAL(K_INSERT), 0);
861 return;
862 case KVAL(K_P1):
863 do_fn(KVAL(K_SELECT), 0);
864 return;
865 case KVAL(K_P2):
866 do_cur(KVAL(K_DOWN), 0);
867 return;
868 case KVAL(K_P3):
869 do_fn(KVAL(K_PGDN), 0);
870 return;
871 case KVAL(K_P4):
872 do_cur(KVAL(K_LEFT), 0);
873 return;
874 case KVAL(K_P6):
875 do_cur(KVAL(K_RIGHT), 0);
876 return;
877 case KVAL(K_P7):
878 do_fn(KVAL(K_FIND), 0);
879 return;
880 case KVAL(K_P8):
881 do_cur(KVAL(K_UP), 0);
882 return;
883 case KVAL(K_P9):
884 do_fn(KVAL(K_PGUP), 0);
885 return;
886 case KVAL(K_P5):
887 applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
888 return;
889 }
890
891 put_queue(pad_chars[value]);
892 if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
893 put_queue(10);
894 }
895
896 static void do_cur(unsigned char value, char up_flag)
897 {
898 static char *cur_chars = "BDCA";
899 if (up_flag)
900 return;
901
902 applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
903 }
904
905 static void do_shift(unsigned char value, char up_flag)
906 {
907 int old_state = shift_state;
908
909 if (rep)
910 return;
911
912
913
914 if (value == KVAL(K_CAPSSHIFT)) {
915 value = KVAL(K_SHIFT);
916 if (!up_flag)
917 clr_vc_kbd_led(kbd, VC_CAPSLOCK);
918 }
919
920 if (up_flag) {
921
922
923 if (k_down[value])
924 k_down[value]--;
925 } else
926 k_down[value]++;
927
928 if (k_down[value])
929 shift_state |= (1 << value);
930 else
931 shift_state &= ~ (1 << value);
932
933
934 if (up_flag && shift_state != old_state && npadch != -1) {
935 if (kbd->kbdmode == VC_UNICODE)
936 to_utf8(npadch & 0xffff);
937 else
938 put_queue(npadch & 0xff);
939 npadch = -1;
940 }
941 }
942
943
944
945
946 void compute_shiftstate(void)
947 {
948 int i, j, k, sym, val;
949
950 shift_state = 0;
951 for(i=0; i < SIZE(k_down); i++)
952 k_down[i] = 0;
953
954 for(i=0; i < SIZE(key_down); i++)
955 if(key_down[i]) {
956 k = (i<<5);
957 for(j=0; j<32; j++,k++)
958 if(test_bit(k, key_down)) {
959 sym = U(plain_map[k]);
960 if(KTYP(sym) == KT_SHIFT) {
961 val = KVAL(sym);
962 if (val == KVAL(K_CAPSSHIFT))
963 val = KVAL(K_SHIFT);
964 k_down[val]++;
965 shift_state |= (1<<val);
966 }
967 }
968 }
969 }
970
971 static void do_meta(unsigned char value, char up_flag)
972 {
973 if (up_flag)
974 return;
975
976 if (vc_kbd_mode(kbd, VC_META)) {
977 put_queue('\033');
978 put_queue(value);
979 } else
980 put_queue(value | 0x80);
981 }
982
983 static void do_ascii(unsigned char value, char up_flag)
984 {
985 int base;
986
987 if (up_flag)
988 return;
989
990 if (value < 10)
991 base = 10;
992 else {
993 value -= 10;
994 base = 16;
995 }
996
997 if (npadch == -1)
998 npadch = value;
999 else
1000 npadch = npadch * base + value;
1001 }
1002
1003 static void do_lock(unsigned char value, char up_flag)
1004 {
1005 if (up_flag || rep)
1006 return;
1007 chg_vc_kbd_lock(kbd, value);
1008 }
1009
1010
1011
1012
1013
1014
1015 static int send_data(unsigned char data)
1016 {
1017 int retries = 3;
1018 int i;
1019
1020 do {
1021 kb_wait();
1022 acknowledge = 0;
1023 resend = 0;
1024 reply_expected = 1;
1025 outb_p(data, 0x60);
1026 for(i=0; i<0x20000; i++) {
1027 inb_p(0x64);
1028 if (acknowledge)
1029 return 1;
1030 if (resend)
1031 break;
1032 }
1033 if (!resend)
1034 return 0;
1035 } while (retries-- > 0);
1036 return 0;
1037 }
1038
1039
1040
1041
1042
1043
1044
1045 static unsigned char ledstate = 0xff;
1046 static unsigned char ledioctl;
1047
1048 unsigned char getledstate(void) {
1049 return ledstate;
1050 }
1051
1052 void setledstate(struct kbd_struct *kbd, unsigned int led) {
1053 if (!(led & ~7)) {
1054 ledioctl = led;
1055 kbd->ledmode = LED_SHOW_IOCTL;
1056 } else
1057 kbd->ledmode = LED_SHOW_FLAGS;
1058 set_leds();
1059 }
1060
1061 static struct ledptr {
1062 unsigned int *addr;
1063 unsigned int mask;
1064 unsigned char valid:1;
1065 } ledptrs[3];
1066
1067 void register_leds(int console, unsigned int led,
1068 unsigned int *addr, unsigned int mask) {
1069 struct kbd_struct *kbd = kbd_table + console;
1070 if (led < 3) {
1071 ledptrs[led].addr = addr;
1072 ledptrs[led].mask = mask;
1073 ledptrs[led].valid = 1;
1074 kbd->ledmode = LED_SHOW_MEM;
1075 } else
1076 kbd->ledmode = LED_SHOW_FLAGS;
1077 }
1078
1079 static inline unsigned char getleds(void){
1080 struct kbd_struct *kbd = kbd_table + fg_console;
1081 unsigned char leds;
1082
1083 if (kbd->ledmode == LED_SHOW_IOCTL)
1084 return ledioctl;
1085 leds = kbd->ledflagstate;
1086 if (kbd->ledmode == LED_SHOW_MEM) {
1087 if (ledptrs[0].valid) {
1088 if (*ledptrs[0].addr & ledptrs[0].mask)
1089 leds |= 1;
1090 else
1091 leds &= ~1;
1092 }
1093 if (ledptrs[1].valid) {
1094 if (*ledptrs[1].addr & ledptrs[1].mask)
1095 leds |= 2;
1096 else
1097 leds &= ~2;
1098 }
1099 if (ledptrs[2].valid) {
1100 if (*ledptrs[2].addr & ledptrs[2].mask)
1101 leds |= 4;
1102 else
1103 leds &= ~4;
1104 }
1105 }
1106 return leds;
1107 }
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122 static void kbd_bh(void * unused)
1123 {
1124 unsigned char leds = getleds();
1125
1126 if (leds != ledstate) {
1127 ledstate = leds;
1128 if (!send_data(0xed) || !send_data(leds))
1129 send_data(0xf4);
1130 }
1131 if (want_console >= 0) {
1132 if (want_console != fg_console) {
1133 last_console = fg_console;
1134 change_console(want_console);
1135
1136
1137
1138 }
1139 want_console = -1;
1140 }
1141 poke_blanked_console();
1142 cli();
1143 if ((inb_p(0x64) & kbd_read_mask) == 0x01)
1144 fake_keyboard_interrupt();
1145 sti();
1146 }
1147
1148 long no_idt[2] = {0, 0};
1149
1150
1151
1152
1153
1154
1155 void hard_reset_now(void)
1156 {
1157 int i, j;
1158 extern unsigned long pg0[1024];
1159
1160 sti();
1161
1162 pg0[0] = 7;
1163 *((unsigned short *)0x472) = 0x1234;
1164 for (;;) {
1165 for (i=0; i<100; i++) {
1166 kb_wait();
1167 for(j = 0; j < 100000 ; j++)
1168 ;
1169 outb(0xfe,0x64);
1170 }
1171 __asm__("\tlidt _no_idt");
1172 }
1173 }
1174
1175 unsigned long kbd_init(unsigned long kmem_start)
1176 {
1177 int i;
1178 struct kbd_struct kbd0;
1179 extern struct tty_driver console_driver;
1180
1181 kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
1182 kbd0.ledmode = LED_SHOW_FLAGS;
1183 kbd0.lockstate = KBD_DEFLOCK;
1184 kbd0.modeflags = KBD_DEFMODE;
1185 kbd0.kbdmode = VC_XLATE;
1186
1187 for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
1188 kbd_table[i] = kbd0;
1189
1190 ttytab = console_driver.table;
1191
1192 bh_base[KEYBOARD_BH].routine = kbd_bh;
1193 request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard");
1194 mark_bh(KEYBOARD_BH);
1195 return kmem_start;
1196 }