This source file includes following definitions.
- kb_wait
- send_cmd
- keyboard_interrupt
- put_queue
- puts_queue
- applkey
- enter
- caps_toggle
- caps_on
- show_ptregs
- hold
- pause
- num
- lastcons
- send_intr
- scrll_forw
- scrll_back
- boot_it
- compose
- SAK
- 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
- kbd_bh
- hard_reset_now
- kbd_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #define KEYBOARD_IRQ 1
15
16 #include <linux/sched.h>
17 #include <linux/interrupt.h>
18 #include <linux/tty.h>
19 #include <linux/tty_flip.h>
20 #include <linux/mm.h>
21 #include <linux/ptrace.h>
22 #include <linux/config.h>
23 #include <linux/signal.h>
24 #include <linux/string.h>
25
26 #include <asm/bitops.h>
27
28 #include "kbd_kern.h"
29 #include "diacr.h"
30 #include "vt_kern.h"
31
32 #define SIZE(x) (sizeof(x)/sizeof((x)[0]))
33
34 #define KBD_REPORT_ERR
35 #define KBD_REPORT_UNKN
36
37 #ifndef KBD_DEFMODE
38 #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
39 #endif
40
41 #ifndef KBD_DEFLEDS
42
43
44
45
46 #define KBD_DEFLEDS 0
47 #endif
48
49 #ifndef KBD_DEFLOCK
50 #define KBD_DEFLOCK 0
51 #endif
52
53
54
55
56
57
58
59 #define REALLY_SLOW_IO
60 #define SLOW_IO_BY_JUMPING
61 #include <asm/io.h>
62 #include <asm/system.h>
63
64 extern void poke_blanked_console(void);
65 extern void ctrl_alt_del(void);
66 extern void change_console(unsigned int new_console);
67 extern void scrollback(int);
68 extern void scrollfront(int);
69
70 #define fake_keyboard_interrupt() \
71 __asm__ __volatile__("int $0x21")
72
73 unsigned char kbd_read_mask = 0x01;
74
75
76
77
78
79
80
81
82 static unsigned char k_down[NR_SHIFT] = {0, };
83
84 static unsigned long key_down[8] = { 0, };
85
86 static int want_console = -1;
87 static int last_console = 0;
88 static int dead_key_next = 0;
89
90
91
92
93
94 int shift_state = 0;
95 static int npadch = -1;
96 static unsigned char diacr = 0;
97 static char rep = 0;
98 struct kbd_struct kbd_table[NR_CONSOLES];
99 static struct tty_struct **ttytab;
100 static struct kbd_struct * kbd = kbd_table;
101 static struct tty_struct * tty = NULL;
102
103
104 static volatile unsigned char acknowledge = 0;
105 static volatile unsigned char resend = 0;
106
107 typedef void (*k_hand)(unsigned char value, char up_flag);
108 typedef void (k_handfn)(unsigned char value, char up_flag);
109
110 static k_handfn
111 do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
112 do_meta, do_ascii, do_lock, do_lowercase;
113
114 static k_hand key_handler[] = {
115 do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
116 do_meta, do_ascii, do_lock, do_lowercase
117 };
118
119
120 const int max_vals[] = {
121 255, NR_FUNC - 1, 15, 17, 4, 255, 3, NR_SHIFT,
122 255, 9, 3, 255
123 };
124
125 const int NR_TYPES = SIZE(max_vals);
126
127 static void put_queue(int);
128 static unsigned char handle_diacr(unsigned char);
129 static void SAK(void);
130
131
132 static struct pt_regs * pt_regs;
133
134 static inline void kb_wait(void)
135 {
136 int i;
137
138 for (i=0; i<0x10000; i++)
139 if ((inb_p(0x64) & 0x02) == 0)
140 break;
141 }
142
143 static inline void send_cmd(unsigned char c)
144 {
145 kb_wait();
146 outb(c,0x64);
147 }
148
149
150
151
152
153 #define E0_BASE 96
154
155 #define E0_KPENTER (E0_BASE+0)
156 #define E0_RCTRL (E0_BASE+1)
157 #define E0_KPSLASH (E0_BASE+2)
158 #define E0_PRSCR (E0_BASE+3)
159 #define E0_RALT (E0_BASE+4)
160 #define E0_BREAK (E0_BASE+5)
161 #define E0_HOME (E0_BASE+6)
162 #define E0_UP (E0_BASE+7)
163 #define E0_PGUP (E0_BASE+8)
164 #define E0_LEFT (E0_BASE+9)
165 #define E0_RIGHT (E0_BASE+10)
166 #define E0_END (E0_BASE+11)
167 #define E0_DOWN (E0_BASE+12)
168 #define E0_PGDN (E0_BASE+13)
169 #define E0_INS (E0_BASE+14)
170 #define E0_DEL (E0_BASE+15)
171
172 #define E0_MACRO (E0_BASE+16)
173
174 #define E0_F13 (E0_BASE+17)
175 #define E0_F14 (E0_BASE+18)
176 #define E0_HELP (E0_BASE+19)
177 #define E0_DO (E0_BASE+20)
178 #define E0_F17 (E0_BASE+21)
179 #define E0_KPMINPLUS (E0_BASE+22)
180
181 #define E1_PAUSE (E0_BASE+23)
182
183 static unsigned char e0_keys[128] = {
184 0, 0, 0, 0, 0, 0, 0, 0,
185 0, 0, 0, 0, 0, 0, 0, 0,
186 0, 0, 0, 0, 0, 0, 0, 0,
187 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,
188 0, 0, 0, 0, 0, 0, 0, 0,
189 0, 0, 0, 0, 0, 0, 0, 0,
190 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,
191 E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,
192 E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,
193 E0_UP, E0_PGUP, 0, E0_LEFT, 0, E0_RIGHT, E0_KPMINPLUS, E0_END,
194 E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,
195 0, 0, 0, 0, 0, 0, 0, 0,
196 0, 0, 0, 0, 0, 0, 0, 0,
197 0, 0, 0, 0, 0, 0, 0, E0_MACRO,
198 0, 0, 0, 0, 0, 0, 0, 0,
199 0, 0, 0, 0, 0, 0, 0, 0
200 };
201
202 static void keyboard_interrupt(int int_pt_regs)
203 {
204 unsigned char scancode;
205 static unsigned int prev_scancode = 0;
206 char up_flag;
207 char raw_mode;
208
209 pt_regs = (struct pt_regs *) int_pt_regs;
210 send_cmd(0xAD);
211 kb_wait();
212 if ((inb_p(0x64) & kbd_read_mask) != 0x01)
213 goto end_kbd_intr;
214 scancode = inb(0x60);
215 mark_bh(KEYBOARD_BH);
216 if (scancode == 0xfa) {
217 acknowledge = 1;
218 goto end_kbd_intr;
219 } else if (scancode == 0xfe) {
220 resend = 1;
221 goto end_kbd_intr;
222 } else if (scancode == 0) {
223 #ifdef KBD_REPORT_ERR
224 printk("keyboard buffer overflow\n");
225 #endif
226 goto end_kbd_intr;
227 } else if (scancode == 0xff) {
228 #ifdef KBD_REPORT_ERR
229 printk("keyboard error\n");
230 #endif
231 prev_scancode = 0;
232 goto end_kbd_intr;
233 }
234 tty = ttytab[fg_console];
235 kbd = kbd_table + fg_console;
236 if ((raw_mode = vc_kbd_mode(kbd,VC_RAW))) {
237 put_queue(scancode);
238
239
240
241 }
242 if (scancode == 0xe0 || scancode == 0xe1) {
243 prev_scancode = scancode;
244 goto end_kbd_intr;
245 }
246
247
248
249
250 up_flag = (scancode & 0200);
251 scancode &= 0x7f;
252
253 if (prev_scancode) {
254
255
256
257
258 if (prev_scancode != 0xe0) {
259 if (prev_scancode == 0xe1 && scancode == 0x1d) {
260 prev_scancode = 0x100;
261 goto end_kbd_intr;
262 } else if (prev_scancode == 0x100 && scancode == 0x45) {
263 scancode = E1_PAUSE;
264 prev_scancode = 0;
265 } else {
266 printk("keyboard: unknown e1 escape sequence\n");
267 prev_scancode = 0;
268 goto end_kbd_intr;
269 }
270 } else {
271 prev_scancode = 0;
272
273
274
275
276
277
278
279
280
281
282
283
284
285 if (scancode == 0x2a || scancode == 0x36)
286 goto end_kbd_intr;
287
288 if (e0_keys[scancode])
289 scancode = e0_keys[scancode];
290 else if (!raw_mode) {
291 #ifdef KBD_REPORT_UNKN
292 printk("keyboard: unknown scancode e0 %02x\n", scancode);
293 #endif
294 goto end_kbd_intr;
295 }
296 }
297 } else if (scancode >= E0_BASE && !raw_mode) {
298 #ifdef KBD_REPORT_UNKN
299 printk("keyboard: scancode (%02x) not in range 00 - %2x\n",
300 scancode, E0_BASE - 1);
301 #endif
302 goto end_kbd_intr;
303 }
304
305
306
307
308
309
310
311
312
313 if (up_flag) {
314 clear_bit(scancode, key_down);
315 rep = 0;
316 } else
317 rep = set_bit(scancode, key_down);
318
319 if (raw_mode)
320 goto end_kbd_intr;
321
322 if (vc_kbd_mode(kbd, VC_MEDIUMRAW)) {
323 put_queue(scancode + up_flag);
324 goto end_kbd_intr;
325 }
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340 if (!rep ||
341 (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
342 (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
343 u_short key_code;
344 u_char type;
345
346
347 int shift_final = shift_state ^ vc_kbd_lock(kbd,VC_CAPSLOCK);
348
349 key_code = key_map[shift_final][scancode];
350 type = KTYP(key_code);
351
352 if (type == KT_LETTER) {
353 type = KT_LATIN;
354 if (vc_kbd_lock(kbd,VC_CAPSLOCK))
355 key_code = key_map[shift_final][scancode];
356 }
357 (*key_handler[type])(key_code & 0xff, up_flag);
358 }
359
360 end_kbd_intr:
361 send_cmd(0xAE);
362 }
363
364 static void put_queue(int ch)
365 {
366 wake_up(&keypress_wait);
367 if (tty) {
368 tty_insert_flip_char(tty, ch, 0);
369 tty_schedule_flip(tty);
370 }
371 }
372
373 static void puts_queue(char *cp)
374 {
375 wake_up(&keypress_wait);
376 if (!tty)
377 return;
378
379 while (*cp) {
380 tty_insert_flip_char(tty, *cp, 0);
381 cp++;
382 }
383 tty_schedule_flip(tty);
384 }
385
386 static void applkey(int key, char mode)
387 {
388 static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
389
390 buf[1] = (mode ? 'O' : '[');
391 buf[2] = key;
392 puts_queue(buf);
393 }
394
395 static void enter(void)
396 {
397 put_queue(13);
398 if (vc_kbd_mode(kbd,VC_CRLF))
399 put_queue(10);
400 }
401
402 static void caps_toggle(void)
403 {
404 if (rep)
405 return;
406 chg_vc_kbd_led(kbd,VC_CAPSLOCK);
407 chg_vc_kbd_lock(kbd,VC_CAPSLOCK);
408 }
409
410 static void caps_on(void)
411 {
412 if (rep)
413 return;
414 set_vc_kbd_led(kbd,VC_CAPSLOCK);
415 set_vc_kbd_lock(kbd,VC_CAPSLOCK);
416 }
417
418 static void show_ptregs(void)
419 {
420 if (!pt_regs)
421 return;
422 printk("\n");
423 printk("EIP: %04x:%08lx",0xffff & pt_regs->cs,pt_regs->eip);
424 if (pt_regs->cs & 3)
425 printk(" ESP: %04x:%08lx",0xffff & pt_regs->ss,pt_regs->esp);
426 printk(" EFLAGS: %08lx\n",pt_regs->eflags);
427 printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
428 pt_regs->orig_eax,pt_regs->ebx,pt_regs->ecx,pt_regs->edx);
429 printk("ESI: %08lx EDI: %08lx EBP: %08lx",
430 pt_regs->esi, pt_regs->edi, pt_regs->ebp);
431 printk(" DS: %04x ES: %04x FS: %04x GS: %04x\n",
432 0xffff & pt_regs->ds,0xffff & pt_regs->es,
433 0xffff & pt_regs->fs,0xffff & pt_regs->gs);
434 }
435
436 static void hold(void)
437 {
438 if (rep || !tty)
439 return;
440
441
442
443
444
445
446 if (tty->stopped)
447 start_tty(tty);
448 else
449 stop_tty(tty);
450 }
451
452 #if 0
453
454 static void pause(void)
455 {
456 chg_vc_kbd_mode(kbd,VC_PAUSE);
457 }
458 #endif
459
460 static void num(void)
461 {
462 if (vc_kbd_mode(kbd,VC_APPLIC)) {
463 applkey('P', 1);
464 return;
465 }
466 if (!rep) {
467 chg_vc_kbd_led(kbd,VC_NUMLOCK);
468 chg_vc_kbd_lock(kbd,VC_NUMLOCK);
469 }
470 }
471
472 static void lastcons(void)
473 {
474
475 want_console = last_console;
476 }
477
478 static void send_intr(void)
479 {
480 if (!tty || (tty->termios && I_IGNBRK(tty)))
481 return;
482 tty_insert_flip_char(tty, 0, TTY_BREAK);
483 }
484
485 static void scrll_forw(void)
486 {
487 scrollfront(0);
488 }
489
490 static void scrll_back(void)
491 {
492 scrollback(0);
493 }
494
495 static void boot_it(void)
496 {
497 ctrl_alt_del();
498 }
499
500 static void compose(void)
501 {
502 dead_key_next = 1;
503 }
504
505 static void SAK(void)
506 {
507 do_SAK(tty);
508 #if 0
509
510
511
512
513
514
515
516
517
518 clr_vc_kbd_flag(kbd, VC_RAW);
519 clr_vc_kbd_flag(kbd, VC_MEDIUMRAW);
520 vt_cons[fg_console].vc_mode = KD_TEXT;
521 vt_cons[fg_console].vt_mode.mode = VT_AUTO;
522 vt_cons[fg_console].vt_mode.waitv = 0;
523 vt_cons[fg_console].vt_mode.relsig = 0;
524 vt_cons[fg_console].vt_mode.acqsig = 0;
525 vt_cons[fg_console].vt_mode.frsig = 0;
526 vt_cons[fg_console].vt_pid = -1;
527 vt_cons[fg_console].vt_newvt = -1;
528 unblank_screen();
529 #endif
530 }
531
532 static void do_spec(unsigned char value, char up_flag)
533 {
534 typedef void (*fnp)(void);
535 fnp fn_table[] = {
536 NULL, enter, show_ptregs, show_mem,
537 show_state, send_intr, lastcons, caps_toggle,
538 num, hold, scrll_forw, scrll_back,
539 boot_it, caps_on, compose, SAK
540 };
541
542 if (up_flag)
543 return;
544 if (value >= SIZE(fn_table))
545 return;
546 if (!fn_table[value])
547 return;
548 fn_table[value]();
549 }
550
551 static void do_lowercase(unsigned char value, char up_flag)
552 {
553 printk("keyboard.c: do_lowercase was called - impossible\n");
554 }
555
556 static void do_self(unsigned char value, char up_flag)
557 {
558 if (up_flag)
559 return;
560
561 if (diacr)
562 value = handle_diacr(value);
563
564 if (dead_key_next) {
565 dead_key_next = 0;
566 diacr = value;
567 return;
568 }
569
570 put_queue(value);
571 }
572
573 #define A_GRAVE '`'
574 #define A_ACUTE '\''
575 #define A_CFLEX '^'
576 #define A_TILDE '~'
577 #define A_DIAER '"'
578 static unsigned char ret_diacr[] =
579 {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER };
580
581
582
583
584 static void do_dead(unsigned char value, char up_flag)
585 {
586 if (up_flag)
587 return;
588
589 value = ret_diacr[value];
590 if (diacr == value) {
591 diacr = 0;
592 put_queue(value);
593 return;
594 }
595 diacr = value;
596 }
597
598
599
600
601
602 unsigned char handle_diacr(unsigned char ch)
603 {
604 int d = diacr;
605 int i;
606
607 diacr = 0;
608 if (ch == ' ')
609 return d;
610
611 for (i = 0; i < accent_table_size; i++) {
612 if (accent_table[i].diacr == d && accent_table[i].base == ch)
613 return accent_table[i].result;
614 }
615
616 put_queue(d);
617 return ch;
618 }
619
620 static void do_cons(unsigned char value, char up_flag)
621 {
622 if (up_flag)
623 return;
624 want_console = value;
625 }
626
627 static void do_fn(unsigned char value, char up_flag)
628 {
629 if (up_flag)
630 return;
631 if (value < SIZE(func_table))
632 puts_queue(func_table[value]);
633 else
634 printk("do_fn called with value=%d\n", value);
635 }
636
637 static void do_pad(unsigned char value, char up_flag)
638 {
639 static char *pad_chars = "0123456789+-*/\015,.?";
640 static char *app_map = "pqrstuvwxylSRQMnn?";
641
642 if (up_flag)
643 return;
644
645
646 if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
647 applkey(app_map[value], 1);
648 return;
649 }
650 if (!vc_kbd_lock(kbd,VC_NUMLOCK))
651 switch (value) {
652 case KVAL(K_PCOMMA):
653 case KVAL(K_PDOT):
654 do_fn(KVAL(K_REMOVE), 0);
655 return;
656 case KVAL(K_P0):
657 do_fn(KVAL(K_INSERT), 0);
658 return;
659 case KVAL(K_P1):
660 do_fn(KVAL(K_SELECT), 0);
661 return;
662 case KVAL(K_P2):
663 do_cur(KVAL(K_DOWN), 0);
664 return;
665 case KVAL(K_P3):
666 do_fn(KVAL(K_PGDN), 0);
667 return;
668 case KVAL(K_P4):
669 do_cur(KVAL(K_LEFT), 0);
670 return;
671 case KVAL(K_P6):
672 do_cur(KVAL(K_RIGHT), 0);
673 return;
674 case KVAL(K_P7):
675 do_fn(KVAL(K_FIND), 0);
676 return;
677 case KVAL(K_P8):
678 do_cur(KVAL(K_UP), 0);
679 return;
680 case KVAL(K_P9):
681 do_fn(KVAL(K_PGUP), 0);
682 return;
683 case KVAL(K_P5):
684 applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
685 return;
686 }
687
688 put_queue(pad_chars[value]);
689 if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
690 put_queue(10);
691 }
692
693 static void do_cur(unsigned char value, char up_flag)
694 {
695 static char *cur_chars = "BDCA";
696 if (up_flag)
697 return;
698
699 applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
700 }
701
702 static void do_shift(unsigned char value, char up_flag)
703 {
704 int old_state = shift_state;
705
706 if (rep)
707 return;
708
709
710 if (value == KVAL(K_CAPSSHIFT)) {
711 value = KVAL(K_SHIFT);
712 if (!up_flag) {
713 clr_vc_kbd_led(kbd, VC_CAPSLOCK);
714 clr_vc_kbd_lock(kbd, VC_CAPSLOCK);
715 }
716 }
717
718 if (up_flag) {
719
720
721 if (k_down[value])
722 k_down[value]--;
723 } else
724 k_down[value]++;
725
726 if (k_down[value])
727 shift_state |= (1 << value);
728 else
729 shift_state &= ~ (1 << value);
730
731
732 if (up_flag && shift_state != old_state && npadch != -1) {
733 put_queue(npadch);
734 npadch = -1;
735 }
736 }
737
738
739
740 void compute_shiftstate(void)
741 {
742 int i, j, k, sym, val;
743
744 shift_state = 0;
745 for(i=0; i < SIZE(k_down); i++)
746 k_down[i] = 0;
747
748 for(i=0; i < SIZE(key_down); i++)
749 if(key_down[i]) {
750 k = (i<<5);
751 for(j=0; j<32; j++,k++)
752 if(test_bit(k, key_down)) {
753 sym = key_map[0][k];
754 if(KTYP(sym) == KT_SHIFT) {
755 val = KVAL(sym);
756 k_down[val]++;
757 shift_state |= (1<<val);
758 }
759 }
760 }
761 }
762
763 static void do_meta(unsigned char value, char up_flag)
764 {
765 if (up_flag)
766 return;
767
768 if (vc_kbd_mode(kbd, VC_META)) {
769 put_queue('\033');
770 put_queue(value);
771 } else
772 put_queue(value | 0x80);
773 }
774
775 static void do_ascii(unsigned char value, char up_flag)
776 {
777 if (up_flag)
778 return;
779
780 if (npadch == -1)
781 npadch = value;
782 else
783 npadch = (npadch * 10 + value) % 1000;
784 }
785
786 static void do_lock(unsigned char value, char up_flag)
787 {
788 if (up_flag || rep)
789 return;
790 chg_vc_kbd_lock(kbd, value);
791 }
792
793
794
795
796
797
798 static int send_data(unsigned char data)
799 {
800 int retries = 3;
801 int i;
802
803 do {
804 kb_wait();
805 acknowledge = 0;
806 resend = 0;
807 outb_p(data, 0x60);
808 for(i=0; i<0x20000; i++) {
809 inb_p(0x64);
810 if (acknowledge)
811 return 1;
812 if (resend)
813 break;
814 }
815 if (!resend)
816 return 0;
817 } while (retries-- > 0);
818 return 0;
819 }
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834 static void kbd_bh(void * unused)
835 {
836 static unsigned char old_leds = 0xff;
837 unsigned char leds = kbd_table[fg_console].ledstate;
838
839 if (leds != old_leds) {
840 old_leds = leds;
841 if (!send_data(0xed) || !send_data(leds))
842 send_data(0xf4);
843 }
844 if (want_console >= 0) {
845 if (want_console != fg_console) {
846 last_console = fg_console;
847 change_console(want_console);
848 }
849 want_console = -1;
850 }
851 poke_blanked_console();
852 cli();
853 if ((inb_p(0x64) & kbd_read_mask) == 0x01)
854 fake_keyboard_interrupt();
855 sti();
856 }
857
858 long no_idt[2] = {0, 0};
859
860
861
862
863
864
865 void hard_reset_now(void)
866 {
867 int i, j;
868 extern unsigned long pg0[1024];
869
870 sti();
871
872 pg0[0] = 7;
873 *((unsigned short *)0x472) = 0x1234;
874 for (;;) {
875 for (i=0; i<100; i++) {
876 kb_wait();
877 for(j = 0; j < 100000 ; j++)
878 ;
879 outb(0xfe,0x64);
880 }
881 __asm__("\tlidt _no_idt");
882 }
883 }
884
885 unsigned long kbd_init(unsigned long kmem_start)
886 {
887 int i;
888 struct kbd_struct * kbd;
889 extern struct tty_driver console_driver;
890
891 kbd = kbd_table + 0;
892 for (i = 0 ; i < NR_CONSOLES ; i++,kbd++) {
893 kbd->ledstate = KBD_DEFLEDS;
894 kbd->default_ledstate = KBD_DEFLEDS;
895 kbd->lockstate = KBD_DEFLOCK;
896 kbd->modeflags = KBD_DEFMODE;
897 }
898 ttytab = console_driver.table;
899
900 bh_base[KEYBOARD_BH].routine = kbd_bh;
901 request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard");
902 mark_bh(KEYBOARD_BH);
903 return kmem_start;
904 }