This source file includes following definitions.
- send_cmd
- vcleds_to_sunkbd
- setkeycode
- getkeycode
- keyboard_timer
- sunkbd_inchar
- 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
- getledstate
- setledstate
- register_leds
- getleds
- kbd_bh
- kbd_init
- push_kbd
- kbd_read
- kbd_fasync
- kbd_select
- kbd_ioctl
- kbd_open
- kbd_close
- keyboard_zsinit
1
2
3
4
5
6
7
8 #include <linux/kernel.h>
9 #include <linux/sched.h>
10 #include <linux/tty.h>
11 #include <linux/tty_flip.h>
12 #include <linux/mm.h>
13 #include <linux/ptrace.h>
14 #include <linux/signal.h>
15 #include <linux/string.h>
16 #include <linux/fcntl.h>
17 #include <asm/kbio.h>
18 #include <asm/vuid_event.h>
19 #include <asm/delay.h>
20 #include <asm/bitops.h>
21 #include <asm/oplib.h>
22
23 #include "../../char/kbd_kern.h"
24 #include "../../char/diacr.h"
25 #include "../../char/vt_kern.h"
26
27 #define SIZE(x) (sizeof(x)/sizeof((x)[0]))
28
29
30
31
32
33
34 #define KBD_MAJOR 11
35
36 #define KBD_REPORT_ERR
37 #define KBD_REPORT_UNKN
38
39 #ifndef KBD_DEFMODE
40 #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
41 #endif
42
43 #ifndef KBD_DEFLEDS
44
45
46
47
48 #define KBD_DEFLEDS 0
49 #endif
50
51 #ifndef KBD_DEFLOCK
52 #define KBD_DEFLOCK 0
53 #endif
54
55 extern void poke_blanked_console(void);
56 extern void ctrl_alt_del(void);
57 extern void reset_vc(unsigned int new_console);
58 extern void scrollback(int);
59 extern void scrollfront(int);
60
61 unsigned char kbd_read_mask = 0x01;
62
63
64
65
66
67
68
69
70 static unsigned char k_down[NR_SHIFT] = {0, };
71
72 #define BITS_PER_LONG (8*sizeof(unsigned long))
73 static unsigned long key_down[256/BITS_PER_LONG] = { 0, };
74
75 void push_kbd (int scan);
76 int kbd_redirected = 0;
77
78 static int dead_key_next = 0;
79
80
81
82
83
84 int shift_state = 0;
85 static int npadch = -1;
86 static unsigned char diacr = 0;
87 static char rep = 0;
88 struct kbd_struct kbd_table[MAX_NR_CONSOLES];
89 static struct tty_struct **ttytab;
90 static struct kbd_struct * kbd = kbd_table;
91 static struct tty_struct * tty = NULL;
92
93 extern void compute_shiftstate(void);
94
95 typedef void (*k_hand)(unsigned char value, char up_flag);
96 typedef void (k_handfn)(unsigned char value, char up_flag);
97
98 static k_handfn
99 do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
100 do_meta, do_ascii, do_lock, do_lowercase, do_ignore;
101
102 static k_hand key_handler[16] = {
103 do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
104 do_meta, do_ascii, do_lock, do_lowercase,
105 do_ignore, do_ignore, do_ignore, do_ignore
106 };
107
108 typedef void (*void_fnp)(void);
109 typedef void (void_fn)(void);
110
111 static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle,
112 num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose,
113 SAK, decr_console, incr_console, spawn_console, bare_num;
114
115 static void_fnp spec_fn_table[] = {
116 do_null, enter, show_ptregs, show_mem,
117 show_state, send_intr, lastcons, caps_toggle,
118 num, hold, scroll_forw, scroll_back,
119 boot_it, caps_on, compose, SAK,
120 decr_console, incr_console, spawn_console, bare_num
121 };
122
123
124 const int max_vals[] = {
125 255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
126 NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
127 255, NR_ASCII - 1, NR_LOCK - 1, 255
128 };
129
130 const int NR_TYPES = SIZE(max_vals);
131
132 static void put_queue(int);
133 static unsigned char handle_diacr(unsigned char);
134
135
136 static struct pt_regs * pt_regs;
137
138 volatile unsigned char sunkbd_layout;
139 volatile unsigned char sunkbd_type;
140 #define SUNKBD_TYPE2 0x02
141 #define SUNKBD_TYPE3 0x03
142 #define SUNKBD_TYPE4 0x04
143
144 #define SUNKBD_LOUT_TYP4 0x00
145 #define SUNKBD_LOUT_TYP5 0x22
146
147 volatile int kbd_reset_pending;
148 volatile int kbd_layout_pending;
149
150
151 #define SKBDCMD_RESET 0x1
152 #define SKBDCMD_GLAYOUT 0xf
153 #define SKBDCMD_BELLON 0x2
154 #define SKBDCMD_BELLOFF 0x3
155 #define SKBDCMD_SETLED 0xe
156 #define SKBDCMD_NOCLICK 0xb
157 #define SKBDCMD_CLICK 0xa
158
159 static unsigned char sunkbd_clickp;
160
161
162
163
164
165 #define LED_NLOCK 0x1
166 #define LED_CMPOSE 0x2
167 #define LED_SCRLCK 0x4
168 #define LED_CLOCK 0x8
169
170
171 #define SKBD_RESET 0xff
172 #define SKBD_ALLUP 0x7f
173 #define SKBD_LYOUT 0xfe
174
175
176
177
178
179
180
181
182
183
184 #define SUNKBD_UBIT 0x80
185 #define SUNKBD_KMASK 0x7f
186
187 #define KEY_LSHIFT 0x81
188 #define KEY_RSHIFT 0x82
189 #define KEY_CONTROL 0x83
190 #define KEY_NILL 0x84
191 #define KEY_CAPSLOCK 0x85
192 #define KEY_ALT 0x86
193 #define KEY_L1 0x87
194
195 extern void kbd_put_char(unsigned char ch);
196 static inline void send_cmd(unsigned char c)
197 {
198 kbd_put_char(c);
199 }
200
201
202
203
204
205
206 static inline unsigned char vcleds_to_sunkbd(unsigned char vcleds)
207 {
208 unsigned char retval = 0;
209
210 if(vcleds & (1<<VC_SCROLLOCK))
211 retval |= LED_SCRLCK;
212 if(vcleds & (1<<VC_NUMLOCK))
213 retval |= LED_NLOCK;
214 if(vcleds & (1<<VC_CAPSLOCK))
215 retval |= LED_CLOCK;
216 return retval;
217 }
218
219
220
221
222
223
224
225
226
227
228
229 #define E0_KPENTER 96
230 #define E0_RCTRL 97
231 #define E0_KPSLASH 98
232 #define E0_PRSCR 99
233 #define E0_RALT 100
234 #define E0_BREAK 101
235 #define E0_HOME 102
236 #define E0_UP 103
237 #define E0_PGUP 104
238 #define E0_LEFT 105
239 #define E0_RIGHT 106
240 #define E0_END 107
241 #define E0_DOWN 108
242 #define E0_PGDN 109
243 #define E0_INS 110
244 #define E0_DEL 111
245
246 #define E1_PAUSE 119
247
248
249
250
251
252
253
254
255 #define SC_LIM 89
256
257 #define FOCUS_PF1 85
258 #define FOCUS_PF2 89
259 #define FOCUS_PF3 90
260 #define FOCUS_PF4 91
261 #define FOCUS_PF5 92
262 #define FOCUS_PF6 93
263 #define FOCUS_PF7 94
264 #define FOCUS_PF8 95
265 #define FOCUS_PF9 120
266 #define FOCUS_PF10 121
267 #define FOCUS_PF11 122
268 #define FOCUS_PF12 123
269
270 #define JAP_86 124
271
272
273
274
275
276
277 #define RGN1 124
278 #define RGN2 125
279 #define RGN3 126
280 #define RGN4 127
281
282 static unsigned char high_keys[128 - SC_LIM] = {
283 RGN1, RGN2, RGN3, RGN4, 0, 0, 0,
284 0, 0, 0, 0, 0, 0, 0, 0,
285 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,
286 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,
287 FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,
288 FOCUS_PF8, JAP_86, FOCUS_PF10, 0
289 };
290
291
292 #define E0_MACRO 112
293
294 #define E0_F13 113
295 #define E0_F14 114
296 #define E0_HELP 115
297 #define E0_DO 116
298 #define E0_F17 117
299 #define E0_KPMINPLUS 118
300
301
302
303
304 #define E0_OK 124
305
306
307
308
309
310
311 #define E0_MSLW 125
312 #define E0_MSRW 126
313 #define E0_MSTM 127
314
315 static unsigned char e0_keys[128] = {
316 0, 0, 0, 0, 0, 0, 0, 0,
317 0, 0, 0, 0, 0, 0, 0, 0,
318 0, 0, 0, 0, 0, 0, 0, 0,
319 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,
320 0, 0, 0, 0, 0, 0, 0, 0,
321 0, 0, 0, 0, 0, 0, 0, 0,
322 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,
323 E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,
324 E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,
325 E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,
326 E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,
327 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,
328 0, 0, 0, 0, 0, 0, 0, 0,
329 0, 0, 0, 0, 0, 0, 0, E0_MACRO,
330 0, 0, 0, 0, 0, 0, 0, 0,
331 0, 0, 0, 0, 0, 0, 0, 0
332 };
333
334 int setkeycode(unsigned int scancode, unsigned int keycode)
335 {
336 if (scancode < SC_LIM || scancode > 255 || keycode > 127)
337 return -EINVAL;
338 if (scancode < 128)
339 high_keys[scancode - SC_LIM] = keycode;
340 else
341 e0_keys[scancode - 128] = keycode;
342 return 0;
343 }
344
345 int getkeycode(unsigned int scancode)
346 {
347 return
348 (scancode < SC_LIM || scancode > 255) ? -EINVAL :
349 (scancode < 128) ? high_keys[scancode - SC_LIM] :
350 e0_keys[scancode - 128];
351 }
352
353 void sunkbd_inchar(unsigned char ch, unsigned char status, struct pt_regs *regs);
354 static void keyboard_timer (unsigned long ignored);
355
356 static struct timer_list
357 auto_repeat_timer = { NULL, NULL, 0, 0, keyboard_timer };
358
359
360 static unsigned char last_keycode;
361
362 static void
363 keyboard_timer (unsigned long ignored)
364 {
365 unsigned long flags;
366
367 save_flags(flags); cli();
368
369
370 sunkbd_inchar (last_keycode, 0, 0);
371 del_timer (&auto_repeat_timer);
372 auto_repeat_timer.expires = jiffies + HZ/20;
373 add_timer (&auto_repeat_timer);
374 restore_flags(flags);
375 }
376
377
378
379 void sunkbd_inchar(unsigned char ch, unsigned char status, struct pt_regs *regs)
380 {
381 unsigned char keycode;
382 char up_flag;
383 char raw_mode;
384
385 if(ch == SKBD_RESET) {
386 kbd_reset_pending = 1;
387 return;
388 }
389 if(ch == SKBD_LYOUT) {
390 kbd_layout_pending = 1;
391 return;
392 }
393 if(kbd_reset_pending) {
394 sunkbd_type = ch;
395 kbd_reset_pending = 0;
396 if(ch == SUNKBD_TYPE4)
397 send_cmd(SKBDCMD_GLAYOUT);
398 return;
399 } else if(kbd_layout_pending) {
400 sunkbd_layout = ch;
401 kbd_layout_pending = 0;
402 return;
403 } else if(ch == SKBD_ALLUP) {
404
405 return;
406 }
407 #ifdef SKBD_DEBUG
408 if(ch == 0x7f)
409 printk("KBD<ALL KEYS UP>");
410 else
411 printk("KBD<%x %s>", ch,
412 ((ch&0x80) ? "UP" : "DOWN"));
413 #endif
414
415
416 if (regs){
417 pt_regs = regs;
418 last_keycode = keycode = ch;
419 } else
420 keycode = ch;
421
422 mark_bh(KEYBOARD_BH);
423 do_poke_blanked_console = 1;
424 mark_bh(CONSOLE_BH);
425 kbd = kbd_table + fg_console;
426 tty = ttytab[fg_console];
427 if((raw_mode = (kbd->kbdmode == VC_RAW))) {
428 if (kbd_redirected == fg_console+1)
429 push_kbd (keycode);
430 else
431 put_queue(keycode);
432
433
434
435
436 }
437 up_flag = (keycode & SUNKBD_UBIT);
438 keycode &= SUNKBD_KMASK;
439 del_timer (&auto_repeat_timer);
440 if(up_flag) {
441 rep = 0;
442 clear_bit(keycode, key_down);
443 } else {
444 auto_repeat_timer.expires = jiffies+HZ/5;
445 add_timer (&auto_repeat_timer);
446 rep = set_bit(keycode, key_down);
447 }
448
449 if(raw_mode)
450 return;
451
452 if(kbd->kbdmode == VC_MEDIUMRAW) {
453 put_queue(keycode + up_flag);
454 return;
455 }
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470 if (!rep ||
471 (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
472 (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
473 u_short keysym;
474 u_char type;
475
476
477 int shift_final = shift_state ^ kbd->lockstate;
478 ushort *key_map = key_maps[shift_final];
479
480 if (key_map != NULL) {
481 keysym = key_map[keycode];
482 type = KTYP(keysym);
483
484 if (type >= 0xf0) {
485 type -= 0xf0;
486 if (type == KT_LETTER) {
487 type = KT_LATIN;
488 if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
489 key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
490 if (key_map)
491 keysym = key_map[keycode];
492 }
493 }
494 (*key_handler[type])(keysym & 0xff, up_flag);
495 if (type != KT_SLOCK)
496 kbd->slockstate = 0;
497 }
498 } else {
499
500
501 compute_shiftstate();
502 }
503 }
504 }
505
506 static void put_queue(int ch)
507 {
508 wake_up(&keypress_wait);
509 if (tty) {
510 tty_insert_flip_char(tty, ch, 0);
511 tty_schedule_flip(tty);
512 }
513 }
514
515 static void puts_queue(char *cp)
516 {
517 wake_up(&keypress_wait);
518 if (!tty)
519 return;
520
521 while (*cp) {
522 tty_insert_flip_char(tty, *cp, 0);
523 cp++;
524 }
525 tty_schedule_flip(tty);
526 }
527
528 static void applkey(int key, char mode)
529 {
530 static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
531
532 buf[1] = (mode ? 'O' : '[');
533 buf[2] = key;
534 puts_queue(buf);
535 }
536
537 static void enter(void)
538 {
539 put_queue(13);
540 if (vc_kbd_mode(kbd,VC_CRLF))
541 put_queue(10);
542 }
543
544 static void caps_toggle(void)
545 {
546 if (rep)
547 return;
548 chg_vc_kbd_led(kbd, VC_CAPSLOCK);
549 }
550
551 static void caps_on(void)
552 {
553 if (rep)
554 return;
555 set_vc_kbd_led(kbd, VC_CAPSLOCK);
556 }
557
558 static void show_ptregs(void)
559 {
560 if (pt_regs)
561 show_regs(pt_regs);
562 }
563
564 static void hold(void)
565 {
566 if (rep || !tty)
567 return;
568
569
570
571
572
573
574 if (tty->stopped)
575 start_tty(tty);
576 else
577 stop_tty(tty);
578 }
579
580 static void num(void)
581 {
582 if (vc_kbd_mode(kbd,VC_APPLIC))
583 applkey('P', 1);
584 else
585 bare_num();
586 }
587
588
589
590
591
592
593
594 static void bare_num(void)
595 {
596 if (!rep)
597 chg_vc_kbd_led(kbd,VC_NUMLOCK);
598 }
599
600 static void lastcons(void)
601 {
602
603 set_console(last_console);
604 }
605
606 static void decr_console(void)
607 {
608 int i;
609
610 for (i = fg_console-1; i != fg_console; i--) {
611 if (i == -1)
612 i = MAX_NR_CONSOLES-1;
613 if (vc_cons_allocated(i))
614 break;
615 }
616 set_console(i);
617 }
618
619 static void incr_console(void)
620 {
621 int i;
622
623 for (i = fg_console+1; i != fg_console; i++) {
624 if (i == MAX_NR_CONSOLES)
625 i = 0;
626 if (vc_cons_allocated(i))
627 break;
628 }
629 set_console(i);
630 }
631
632 static void send_intr(void)
633 {
634 if (!tty)
635 return;
636 tty_insert_flip_char(tty, 0, TTY_BREAK);
637 tty_schedule_flip(tty);
638 }
639
640 static void scroll_forw(void)
641 {
642 scrollfront(0);
643 }
644
645 static void scroll_back(void)
646 {
647 scrollback(0);
648 }
649
650 static void boot_it(void)
651 {
652 extern int obp_system_intr(void);
653
654 if (!obp_system_intr())
655 ctrl_alt_del();
656
657 last_keycode=1;
658 rep = 0;
659 }
660
661 static void compose(void)
662 {
663 dead_key_next = 1;
664 }
665
666 int spawnpid, spawnsig;
667
668 static void spawn_console(void)
669 {
670 if (spawnpid)
671 if(kill_proc(spawnpid, spawnsig, 1))
672 spawnpid = 0;
673 }
674
675 static void SAK(void)
676 {
677 do_SAK(tty);
678 #if 0
679
680
681
682
683
684
685
686
687
688 reset_vc(fg_console);
689 do_unblank_screen();
690 #endif
691 }
692
693 static void do_ignore(unsigned char value, char up_flag)
694 {
695 }
696
697 static void do_null()
698 {
699 compute_shiftstate();
700 }
701
702 static void do_spec(unsigned char value, char up_flag)
703 {
704 if (up_flag)
705 return;
706 if (value >= SIZE(spec_fn_table))
707 return;
708 spec_fn_table[value]();
709 }
710
711 static void do_lowercase(unsigned char value, char up_flag)
712 {
713 printk("keyboard.c: do_lowercase was called - impossible\n");
714 }
715
716 static void do_self(unsigned char value, char up_flag)
717 {
718 if (up_flag)
719 return;
720
721 if (diacr)
722 value = handle_diacr(value);
723
724 if (dead_key_next) {
725 dead_key_next = 0;
726 diacr = value;
727 return;
728 }
729
730 put_queue(value);
731 }
732
733 #define A_GRAVE '`'
734 #define A_ACUTE '\''
735 #define A_CFLEX '^'
736 #define A_TILDE '~'
737 #define A_DIAER '"'
738 static unsigned char ret_diacr[] =
739 {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER };
740
741
742
743
744 static void do_dead(unsigned char value, char up_flag)
745 {
746 if (up_flag)
747 return;
748
749 value = ret_diacr[value];
750 if (diacr == value) {
751 diacr = 0;
752 put_queue(value);
753 return;
754 }
755 diacr = value;
756 }
757
758
759
760
761
762 unsigned char handle_diacr(unsigned char ch)
763 {
764 int d = diacr;
765 int i;
766
767 diacr = 0;
768 if (ch == ' ')
769 return d;
770
771 for (i = 0; i < accent_table_size; i++) {
772 if (accent_table[i].diacr == d && accent_table[i].base == ch)
773 return accent_table[i].result;
774 }
775
776 put_queue(d);
777 return ch;
778 }
779
780 static void do_cons(unsigned char value, char up_flag)
781 {
782 if (up_flag)
783 return;
784 want_console = value;
785 }
786
787 static void do_fn(unsigned char value, char up_flag)
788 {
789 if (up_flag)
790 return;
791 if (value < SIZE(func_table)) {
792 if (func_table[value])
793 puts_queue(func_table[value]);
794 } else
795 printk("do_fn called with value=%d\n", value);
796 }
797
798 static void do_pad(unsigned char value, char up_flag)
799 {
800 static const char *pad_chars = "0123456789+-*/\015,.?";
801 static const char *app_map = "pqrstuvwxylSRQMnn?";
802
803 if (up_flag)
804 return;
805
806
807 if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
808 applkey(app_map[value], 1);
809 return;
810 }
811
812 if (!vc_kbd_led(kbd,VC_NUMLOCK))
813 switch (value) {
814 case KVAL(K_PCOMMA):
815 case KVAL(K_PDOT):
816 do_fn(KVAL(K_REMOVE), 0);
817 return;
818 case KVAL(K_P0):
819 do_fn(KVAL(K_INSERT), 0);
820 return;
821 case KVAL(K_P1):
822 do_fn(KVAL(K_SELECT), 0);
823 return;
824 case KVAL(K_P2):
825 do_cur(KVAL(K_DOWN), 0);
826 return;
827 case KVAL(K_P3):
828 do_fn(KVAL(K_PGDN), 0);
829 return;
830 case KVAL(K_P4):
831 do_cur(KVAL(K_LEFT), 0);
832 return;
833 case KVAL(K_P6):
834 do_cur(KVAL(K_RIGHT), 0);
835 return;
836 case KVAL(K_P7):
837 do_fn(KVAL(K_FIND), 0);
838 return;
839 case KVAL(K_P8):
840 do_cur(KVAL(K_UP), 0);
841 return;
842 case KVAL(K_P9):
843 do_fn(KVAL(K_PGUP), 0);
844 return;
845 case KVAL(K_P5):
846 applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
847 return;
848 }
849
850 put_queue(pad_chars[value]);
851 if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
852 put_queue(10);
853 }
854
855 static void do_cur(unsigned char value, char up_flag)
856 {
857 static const char *cur_chars = "BDCA";
858 if (up_flag)
859 return;
860
861 applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
862 }
863
864 static void do_shift(unsigned char value, char up_flag)
865 {
866 int old_state = shift_state;
867
868 if (rep)
869 return;
870
871
872
873 if (value == KVAL(K_CAPSSHIFT)) {
874 value = KVAL(K_SHIFT);
875 if (!up_flag)
876 clr_vc_kbd_led(kbd, VC_CAPSLOCK);
877 }
878
879 if (up_flag) {
880
881
882 if (k_down[value])
883 k_down[value]--;
884 } else
885 k_down[value]++;
886
887 if (k_down[value])
888 shift_state |= (1 << value);
889 else
890 shift_state &= ~ (1 << value);
891
892
893 if (up_flag && shift_state != old_state && npadch != -1) {
894 put_queue(npadch & 0xff);
895 npadch = -1;
896 }
897 }
898
899
900
901
902 void compute_shiftstate(void)
903 {
904 int i, j, k, sym, val;
905
906 shift_state = 0;
907 for(i=0; i < SIZE(k_down); i++)
908 k_down[i] = 0;
909
910 for(i=0; i < SIZE(key_down); i++)
911 if(key_down[i]) {
912 k = i*BITS_PER_LONG;
913 for(j=0; j<BITS_PER_LONG; j++,k++)
914 if(test_bit(k, key_down)) {
915 sym = U(plain_map[k]);
916 if(KTYP(sym) == KT_SHIFT) {
917 val = KVAL(sym);
918 if (val == KVAL(K_CAPSSHIFT))
919 val = KVAL(K_SHIFT);
920 k_down[val]++;
921 shift_state |= (1<<val);
922 }
923 }
924 }
925 }
926
927 static void do_meta(unsigned char value, char up_flag)
928 {
929 if (up_flag)
930 return;
931
932 if (vc_kbd_mode(kbd, VC_META)) {
933 put_queue('\033');
934 put_queue(value);
935 } else
936 put_queue(value | 0x80);
937 }
938
939 static void do_ascii(unsigned char value, char up_flag)
940 {
941 int base;
942
943 if (up_flag)
944 return;
945
946 if (value < 10)
947 base = 10;
948 else {
949 value -= 10;
950 base = 16;
951 }
952
953 if (npadch == -1)
954 npadch = value;
955 else
956 npadch = npadch * base + value;
957 }
958
959 static void do_lock(unsigned char value, char up_flag)
960 {
961 if (up_flag || rep)
962 return;
963 chg_vc_kbd_lock(kbd, value);
964 }
965
966
967
968
969
970
971
972 static unsigned char ledstate = 0xff;
973 static unsigned char ledioctl;
974
975 unsigned char getledstate(void) {
976 return ledstate;
977 }
978
979 void setledstate(struct kbd_struct *kbd, unsigned int led) {
980 if (!(led & ~7)) {
981 ledioctl = led;
982 kbd->ledmode = LED_SHOW_IOCTL;
983 } else
984 kbd->ledmode = LED_SHOW_FLAGS;
985 set_leds();
986 }
987
988 static struct ledptr {
989 unsigned int *addr;
990 unsigned int mask;
991 unsigned char valid:1;
992 } ledptrs[3];
993
994 void register_leds(int console, unsigned int led,
995 unsigned int *addr, unsigned int mask) {
996 struct kbd_struct *kbd = kbd_table + console;
997 if (led < 3) {
998 ledptrs[led].addr = addr;
999 ledptrs[led].mask = mask;
1000 ledptrs[led].valid = 1;
1001 kbd->ledmode = LED_SHOW_MEM;
1002 } else
1003 kbd->ledmode = LED_SHOW_FLAGS;
1004 }
1005
1006 static inline unsigned char getleds(void){
1007 struct kbd_struct *kbd = kbd_table + fg_console;
1008 unsigned char leds;
1009
1010 if (kbd->ledmode == LED_SHOW_IOCTL)
1011 return ledioctl;
1012 leds = kbd->ledflagstate;
1013 if (kbd->ledmode == LED_SHOW_MEM) {
1014 if (ledptrs[0].valid) {
1015 if (*ledptrs[0].addr & ledptrs[0].mask)
1016 leds |= 1;
1017 else
1018 leds &= ~1;
1019 }
1020 if (ledptrs[1].valid) {
1021 if (*ledptrs[1].addr & ledptrs[1].mask)
1022 leds |= 2;
1023 else
1024 leds &= ~2;
1025 }
1026 if (ledptrs[2].valid) {
1027 if (*ledptrs[2].addr & ledptrs[2].mask)
1028 leds |= 4;
1029 else
1030 leds &= ~4;
1031 }
1032 }
1033 return leds;
1034 }
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 static void kbd_bh(void)
1050 {
1051 unsigned char leds = getleds();
1052
1053 if (leds != ledstate) {
1054 ledstate = leds;
1055 send_cmd(SKBDCMD_SETLED);
1056 send_cmd(vcleds_to_sunkbd(leds));
1057 }
1058 }
1059
1060 int kbd_init(void)
1061 {
1062 int i, opt_node;
1063 struct kbd_struct kbd0;
1064 extern struct tty_driver console_driver;
1065
1066 kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
1067 kbd0.ledmode = LED_SHOW_FLAGS;
1068 kbd0.lockstate = KBD_DEFLOCK;
1069 kbd0.modeflags = KBD_DEFMODE;
1070 kbd0.kbdmode = VC_XLATE;
1071
1072 for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
1073 kbd_table[i] = kbd0;
1074
1075 ttytab = console_driver.table;
1076
1077
1078 if(sparc_cpu_model != sun4) {
1079 opt_node = prom_getchild(prom_root_node);
1080 opt_node = prom_searchsiblings(opt_node, "options");
1081 i = prom_getintdefault(opt_node, "keyboard-click?", -1);
1082 if(i != -1)
1083 sunkbd_clickp = 1;
1084 else
1085 sunkbd_clickp = 0;
1086 } else {
1087 sunkbd_clickp = 0;
1088 }
1089 init_bh(KEYBOARD_BH, kbd_bh);
1090 mark_bh(KEYBOARD_BH);
1091 return 0;
1092 }
1093
1094
1095
1096 #define KBD_QSIZE 32
1097 static Firm_event kbd_queue [KBD_QSIZE];
1098 static int kbd_head, kbd_tail;
1099 char kbd_opened;
1100 static struct wait_queue *kbd_wait;
1101 static struct fasync_struct *kb_fasync;
1102
1103 void
1104 push_kbd (int scan)
1105 {
1106 int next = (kbd_head + 1) % KBD_QSIZE;
1107
1108 if (scan == KBD_IDLE)
1109 return;
1110 if (next != kbd_tail){
1111 kbd_queue [kbd_head].id = scan & KBD_KEYMASK;
1112 kbd_queue [kbd_head].value=scan & KBD_UP ? VKEY_UP : VKEY_DOWN;
1113 kbd_queue [kbd_head].time = xtime;
1114 kbd_head = next;
1115 }
1116 if (kb_fasync)
1117 kill_fasync (kb_fasync, SIGIO);
1118 wake_up_interruptible (&kbd_wait);
1119 }
1120
1121 static int
1122 kbd_read (struct inode *inode, struct file *f, char *buffer, int count)
1123 {
1124 struct wait_queue wait = { current, NULL };
1125 char *end, *p;
1126
1127
1128 if (kbd_head == kbd_tail){
1129 if (f->f_flags & O_NONBLOCK)
1130 return -EWOULDBLOCK;
1131 add_wait_queue (&kbd_wait, &wait);
1132 while (kbd_head == kbd_tail && !(current->signal & ~current->blocked)){
1133 current->state = TASK_INTERRUPTIBLE;
1134 schedule ();
1135 }
1136 current->state = TASK_RUNNING;
1137 remove_wait_queue (&kbd_wait, &wait);
1138 }
1139
1140 end = buffer+count;
1141 p = buffer;
1142 for (; p < end && kbd_head != kbd_tail; p += sizeof (Firm_event)){
1143 *(Firm_event *)p = kbd_queue [kbd_tail];
1144 #ifdef KBD_DEBUG
1145 printk ("[%s]", kbd_queue [kbd_tail].value == VKEY_UP ? "UP" : "DOWN");
1146 #endif
1147 kbd_tail++;
1148 kbd_tail %= KBD_QSIZE;
1149 }
1150 return p-buffer;
1151 }
1152
1153
1154 static int
1155 kbd_fasync (struct inode *inode, struct file *filp, int on)
1156 {
1157 int retval;
1158
1159 retval = fasync_helper (inode, filp, on, &kb_fasync);
1160 if (retval < 0)
1161 return retval;
1162 return 0;
1163 }
1164
1165 static int
1166 kbd_select (struct inode *i, struct file *f, int sel_type, select_table *wait)
1167 {
1168 if (sel_type != SEL_IN)
1169 return 0;
1170 if (kbd_head != kbd_tail)
1171 return 1;
1172 select_wait (&kbd_wait, wait);
1173 return 0;
1174 }
1175
1176 static int
1177 kbd_ioctl (struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
1178 {
1179 switch (cmd){
1180 case KIOCTYPE:
1181 if (verify_area (VERIFY_WRITE, (void *)arg, sizeof (int)))
1182 return -EFAULT;
1183 *(int *) arg = sunkbd_type;
1184 break;
1185 case KIOCGTRANS:
1186 if (verify_area (VERIFY_WRITE, (void *) arg, sizeof (int)))
1187 return -EFAULT;
1188 *(int *) arg = TR_UNTRANS_EVENT;
1189 break;
1190 case KIOCTRANS:
1191 if (verify_area (VERIFY_READ, (void *) arg, sizeof (int)))
1192 return -EFAULT;
1193 if (*(int *) arg != TR_UNTRANS_EVENT)
1194 return -EINVAL;
1195 break;
1196 case KIOCLAYOUT:
1197 if (verify_area (VERIFY_WRITE, (void *) arg, sizeof (int)))
1198 return -EFAULT;
1199 *(int *) arg = sunkbd_layout;
1200 break;
1201 case KIOCSDIRECT:
1202 if (verify_area (VERIFY_WRITE, (void *) arg, sizeof (int)))
1203 return -EFAULT;
1204 #ifndef CODING_NEW_DRIVER
1205 if (*(int *) arg)
1206 kbd_redirected = fg_console + 1;
1207 else
1208 kbd_redirected = 0;
1209 kbd_table [fg_console].kbdmode = kbd_redirected ? VC_RAW : VC_XLATE;
1210 #endif
1211 break;
1212 case KIOCCMD:
1213
1214 return 0;
1215 case FIONREAD:
1216 {
1217 int count;
1218
1219 if (verify_area (VERIFY_WRITE, (void *) arg, sizeof (int)))
1220 return -EFAULT;
1221 count = kbd_head - kbd_tail;
1222 * (int *)arg = (count < 0) ? KBD_QSIZE - count : count;
1223 return 0;
1224 }
1225 default:
1226 printk ("Unknown Keyboard ioctl: %8.8x\n", cmd);
1227 return -EINVAL;
1228 }
1229 return 0;
1230 }
1231
1232 static int
1233 kbd_open (struct inode *i, struct file *f)
1234 {
1235 if (kbd_opened)
1236 return 0;
1237 kbd_opened = fg_console + 1;
1238 kbd_head = kbd_tail = 0;
1239 return 0;
1240 }
1241
1242 static void
1243 kbd_close (struct inode *i, struct file *f)
1244 {
1245 if (kbd_redirected)
1246 kbd_table [kbd_opened-1].kbdmode = VC_XLATE;
1247 kbd_redirected = 0;
1248 kbd_opened = 0;
1249
1250 kbd_fasync (i, f, 0);
1251 }
1252
1253 static struct
1254 file_operations kbd_fops =
1255 {
1256 NULL,
1257 kbd_read,
1258 NULL,
1259 NULL,
1260 kbd_select,
1261 kbd_ioctl,
1262 NULL,
1263 kbd_open,
1264 kbd_close,
1265 NULL,
1266 kbd_fasync,
1267 NULL,
1268 NULL,
1269 };
1270
1271 void
1272 keyboard_zsinit(void)
1273 {
1274 int timeout = 0;
1275
1276
1277 sunkbd_type = 255;
1278 send_cmd(SKBDCMD_RESET);
1279 while((sunkbd_type==255) && timeout < 500000) {
1280 udelay(100);
1281 timeout += 20;
1282 }
1283
1284 if(timeout>=500000) {
1285 printk("keyboard: not present\n");
1286 return;
1287 }
1288
1289 if(sunkbd_type != SUNKBD_TYPE4) {
1290 printk("Sun TYPE %d keyboard detected ", sunkbd_type);
1291 } else {
1292 udelay(200);
1293 timeout=0;
1294 while(timeout++ < 500000)
1295 barrier();
1296 printk("Sun TYPE %d keyboard detected ",
1297 ((sunkbd_layout==SUNKBD_LOUT_TYP5) ? 5 : 4));
1298 }
1299 if(sunkbd_type == SUNKBD_TYPE2)
1300 sunkbd_clickp = 0;
1301
1302 if(sunkbd_clickp)
1303 printk("with keyclick\n");
1304 else
1305 printk("without keyclick\n");
1306
1307
1308 send_cmd(SKBDCMD_SETLED); send_cmd(0xf);
1309 send_cmd(SKBDCMD_SETLED); send_cmd(0x0);
1310
1311
1312 if (register_chrdev (KBD_MAJOR, "kbd", &kbd_fops)){
1313 printk ("Could not register /dev/kbd device\n");
1314 return;
1315 }
1316 return;
1317 }