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