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