1 /* keyboard.c: Sun keyboard driver. 3 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 4 * Added vuid event generation and /dev/kbd device for SunOS 5 * compatibility - Miguel (miguel@nuclecu.unam.mx) 8 #include <linux/kernel.h> 9 #include <linux/sched.h> 10 #include <linux/tty.h> 11 #include <linux/tty_flip.h> 13 #include <linux/ptrace.h> 14 #include <linux/signal.h> 15 #include <linux/string.h> 16 #include <linux/fcntl.h> 17 #include <linux/poll.h> 18 #include <linux/random.h> 19 #include <linux/init.h> 22 #include <asm/vuid_event.h> 23 #include <asm/delay.h> 24 #include <asm/bitops.h> 25 #include <asm/oplib.h> 26 #include <asm/uaccess.h> 28 #include"../../char/kbd_kern.h" 29 #include"../../char/diacr.h" 30 #include"../../char/vt_kern.h" 32 #define SIZE(x) (sizeof(x)/sizeof((x)[0])) 34 /* Define this one if you are making a new frame buffer driver */ 35 /* it will not block the keyboard */ 36 /* #define CODING_NEW_DRIVER */ 38 /* KBD device number, temporal */ 41 #define KBD_REPORT_ERR 42 #define KBD_REPORT_UNKN 45 #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META)) 50 * Some laptops take the 789uiojklm,. keys as number pad when NumLock 51 * is on. This seems a good reason to start with NumLock off. 60 externvoidpoke_blanked_console(void); 61 externvoidctrl_alt_del(void); 62 externvoidreset_vc(unsigned int new_console
); 63 externvoidscrollback(int); 64 externvoidscrollfront(int); 66 unsigned char kbd_read_mask
=0x01;/* modified by psaux.c */ 67 unsigned char aux_device_present
=0x00;/* To make kernel/ksyms.c happy */ 69 struct wait_queue
* keypress_wait
= NULL
; 71 voidkeyboard_wait_for_keypress(void) 73 sleep_on(&keypress_wait
); 77 * global state includes the following, and various static variables 78 * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next. 79 * (last_console is now a global variable) 82 /* shift state counters.. */ 83 static unsigned char k_down
[NR_SHIFT
] = {0, }; 84 /* keyboard key bitmap */ 85 #define BITS_PER_LONG (8*sizeof(unsigned long)) 86 static unsigned long key_down
[256/BITS_PER_LONG
] = {0, }; 88 voidpush_kbd(int scan
); 89 int kbd_redirected
=0; 91 static int dead_key_next
=0; 93 * In order to retrieve the shift_state (for the mouse server), either 94 * the variable must be global, or a new procedure must be created to 95 * return the value. I chose the former way. 97 /*static*/int shift_state
=0; 98 static int npadch
= -1;/* -1 or number assembled on pad */ 99 static unsigned char diacr
=0; 100 static char rep
=0;/* flag telling character repeat */ 101 struct kbd_struct kbd_table
[MAX_NR_CONSOLES
]; 102 static struct tty_struct
**ttytab
; 103 static struct kbd_struct
* kbd
= kbd_table
; 104 static struct tty_struct
* tty
= NULL
; 105 static int compose_led_on
=0; 106 static int kbd_delay_ticks
= HZ
/5; 107 static int kbd_rate_ticks
= HZ
/20; 109 externvoidcompute_shiftstate(void); 111 typedefvoid(*k_hand
)(unsigned char value
,char up_flag
); 112 typedefvoid(k_handfn
)(unsigned char value
,char up_flag
); 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
, do_ignore
; 118 static k_hand key_handler
[16] = { 119 do_self
, do_fn
, do_spec
, do_pad
, do_dead
, do_cons
, do_cur
, do_shift
, 120 do_meta
, do_ascii
, do_lock
, do_lowercase
, 121 do_ignore
, do_ignore
, do_ignore
, do_ignore
124 typedefvoid(*void_fnp
)(void); 125 typedefvoid(void_fn
)(void); 127 static void_fn do_null
, enter
, show_ptregs
, send_intr
, lastcons
, caps_toggle
, 128 num
, hold
, scroll_forw
, scroll_back
, boot_it
, caps_on
, compose
, 129 SAK
, decr_console
, incr_console
, spawn_console
, bare_num
; 131 static void_fnp spec_fn_table
[] = { 132 do_null
, enter
, show_ptregs
, show_mem
, 133 show_state
, send_intr
, lastcons
, caps_toggle
, 134 num
, hold
, scroll_forw
, scroll_back
, 135 boot_it
, caps_on
, compose
, SAK
, 136 decr_console
, incr_console
, spawn_console
, bare_num
139 /* maximum values each key_handler can handle */ 140 const int max_vals
[] = { 141 255,SIZE(func_table
) -1,SIZE(spec_fn_table
) -1, NR_PAD
-1, 142 NR_DEAD
-1,255,3, NR_SHIFT
-1, 143 255, NR_ASCII
-1, NR_LOCK
-1,255 146 const int NR_TYPES
=SIZE(max_vals
); 148 static voidput_queue(int); 149 static unsigned charhandle_diacr(unsigned char); 151 /* pt_regs - set by keyboard_interrupt(), used by show_ptregs() */ 152 static struct pt_regs
* pt_regs
; 154 volatileunsigned char sunkbd_layout
; 155 volatileunsigned char sunkbd_type
; 156 #define SUNKBD_TYPE2 0x02 157 #define SUNKBD_TYPE3 0x03 158 #define SUNKBD_TYPE4 0x04 160 #define SUNKBD_LOUT_TYP4 0x00 161 #define SUNKBD_LOUT_TYP5_MASK 0x20 163 volatileint kbd_reset_pending
; 164 volatileint kbd_layout_pending
; 167 #define SKBDCMD_RESET 0x1 168 #define SKBDCMD_GLAYOUT 0xf 169 #define SKBDCMD_BELLON 0x2 170 #define SKBDCMD_BELLOFF 0x3 171 #define SKBDCMD_SETLED 0xe 172 #define SKBDCMD_NOCLICK 0xb 173 #define SKBDCMD_CLICK 0xa 175 static unsigned char sunkbd_clickp
; 177 /* The led set commands require sending the SETLED byte then 178 * a byte encoding which led's to have set. Here are the bit 179 * values, a bit set = led-on. 181 #define LED_NLOCK 0x1/* Num-lock */ 182 #define LED_CMPOSE 0x2/* Compose */ 183 #define LED_SCRLCK 0x4/* Scroll-lock */ 184 #define LED_CLOCK 0x8/* Caps-lock */ 186 /* Special state characters */ 187 #define SKBD_RESET 0xff 188 #define SKBD_ALLUP 0x7f 189 #define SKBD_LYOUT 0xfe 191 /* On the Sparc the keyboard could be one of two things. 192 * It could be a real keyboard speaking over one of the 193 * channels of the second zs8530 chip (other channel is 194 * used by the Sun mouse). Else we have serial console 195 * going, and thus the other zs8530 chip is who we speak 196 * to. Either way, we communicate through the zs8530 197 * driver for all our I/O. 200 #define SUNKBD_UBIT 0x80/* If set, key went up */ 201 #define SUNKBD_KMASK 0x7f/* Other bits are the keycode */ 203 #define KEY_LSHIFT 0x81 204 #define KEY_RSHIFT 0x82 205 #define KEY_CONTROL 0x83 206 #define KEY_NILL 0x84 207 #define KEY_CAPSLOCK 0x85 211 externvoidkbd_put_char(unsigned char ch
); 212 staticinlinevoidsend_cmd(unsigned char c
) 217 /* kbd_bh() calls this to send the SKBDCMD_SETLED to the sun keyboard 218 * with the proper bit pattern for the leds to be set. It basically 219 * converts the kbd->ledflagstate values to corresponding sun kbd led 222 staticinlineunsigned charvcleds_to_sunkbd(unsigned char vcleds
) 224 unsigned char retval
=0; 226 if(vcleds
& (1<<VC_SCROLLOCK
)) 227 retval
|= LED_SCRLCK
; 228 if(vcleds
& (1<<VC_NUMLOCK
)) 230 if(vcleds
& (1<<VC_CAPSLOCK
)) 233 retval
|= LED_CMPOSE
; 238 * Translation of escaped scancodes to keycodes. 239 * This is now user-settable. 240 * The keycodes 1-88,96-111,119 are fairly standard, and 241 * should probably not be changed - changing might confuse X. 242 * X also interprets scancode 0x5d (KEY_Begin). 244 * For 1-88 keycode equals scancode. 247 #define E0_KPENTER 96 249 #define E0_KPSLASH 98 252 #define E0_BREAK 101/* (control-pause) */ 267 * The keycodes below are randomly located in 89-95,112-118,120-127. 268 * They could be thrown away (and all occurrences below replaced by 0), 269 * but that would force many users to use the `setkeycodes' utility, where 270 * they needed not before. It does not matter that there are duplicates, as 271 * long as no duplication occurs for any single keyboard. 275 #define FOCUS_PF1 85/* actual code! */ 283 #define FOCUS_PF9 120 284 #define FOCUS_PF10 121 285 #define FOCUS_PF11 122 286 #define FOCUS_PF12 123 289 /* tfj@olivia.ping.dk: 290 * The four keys are located over the numeric keypad, and are 291 * labelled A1-A4. It's an rc930 keyboard, from 292 * Regnecentralen/RC International, Now ICL. 293 * Scancodes: 59, 5a, 5b, 5c. 300 static unsigned char high_keys
[128- SC_LIM
] = { 301 RGN1
, RGN2
, RGN3
, RGN4
,0,0,0,/* 0x59-0x5f */ 302 0,0,0,0,0,0,0,0,/* 0x60-0x67 */ 303 0,0,0,0,0, FOCUS_PF11
,0, FOCUS_PF12
,/* 0x68-0x6f */ 304 0,0,0, FOCUS_PF2
, FOCUS_PF9
,0,0, FOCUS_PF3
,/* 0x70-0x77 */ 305 FOCUS_PF4
, FOCUS_PF5
, FOCUS_PF6
, FOCUS_PF7
,/* 0x78-0x7b */ 306 FOCUS_PF8
, JAP_86
, FOCUS_PF10
,0/* 0x7c-0x7f */ 317 #define E0_KPMINPLUS 118 319 * My OmniKey generates e0 4c for the "OMNI" key and the 320 * right alt key does nada. [kkoller@nyx10.cs.du.edu] 324 * New microsoft keyboard is rumoured to have 325 * e0 5b (left window button), e0 5c (right window button), 326 * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU] 327 * [or: Windows_L, Windows_R, TaskMan] 333 static unsigned char e0_keys
[128] = { 334 0,0,0,0,0,0,0,0,/* 0x00-0x07 */ 335 0,0,0,0,0,0,0,0,/* 0x08-0x0f */ 336 0,0,0,0,0,0,0,0,/* 0x10-0x17 */ 337 0,0,0,0, E0_KPENTER
, E0_RCTRL
,0,0,/* 0x18-0x1f */ 338 0,0,0,0,0,0,0,0,/* 0x20-0x27 */ 339 0,0,0,0,0,0,0,0,/* 0x28-0x2f */ 340 0,0,0,0,0, E0_KPSLASH
,0, E0_PRSCR
,/* 0x30-0x37 */ 341 E0_RALT
,0,0,0,0, E0_F13
, E0_F14
, E0_HELP
,/* 0x38-0x3f */ 342 E0_DO
, E0_F17
,0,0,0,0, E0_BREAK
, E0_HOME
,/* 0x40-0x47 */ 343 E0_UP
, E0_PGUP
,0, E0_LEFT
, E0_OK
, E0_RIGHT
, E0_KPMINPLUS
, E0_END
,/* 0x48-0x4f */ 344 E0_DOWN
, E0_PGDN
, E0_INS
, E0_DEL
,0,0,0,0,/* 0x50-0x57 */ 345 0,0,0, E0_MSLW
, E0_MSRW
, E0_MSTM
,0,0,/* 0x58-0x5f */ 346 0,0,0,0,0,0,0,0,/* 0x60-0x67 */ 347 0,0,0,0,0,0,0, E0_MACRO
,/* 0x68-0x6f */ 348 0,0,0,0,0,0,0,0,/* 0x70-0x77 */ 349 0,0,0,0,0,0,0,0/* 0x78-0x7f */ 352 /* we use this map to determine if a particular key should not be 353 autorepeated. We don't autorepeat CONTROL, LSHIFT, CAPS, 354 ALT, LMETA, RSHIFT, RMETA, ALTG and COMPOSE */ 355 static unsigned char norepeat_keys
[128] = { 356 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,/* 0x00-0x0f */ 357 0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,/* 0x10-0x1f */ 358 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,/* 0x20-0x2f */ 359 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,/* 0x30-0x3f */ 360 0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,/* 0x40-0x4f */ 361 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,/* 0x50-0x5f */ 362 0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,/* 0x60-0x6f */ 363 0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,/* 0x70-0x7f */ 367 intsetkeycode(unsigned int scancode
,unsigned int keycode
) 369 if(scancode
< SC_LIM
|| scancode
>255|| keycode
>127) 372 high_keys
[scancode
- SC_LIM
] = keycode
; 374 e0_keys
[scancode
-128] = keycode
; 378 intgetkeycode(unsigned int scancode
) 381 (scancode
< SC_LIM
|| scancode
>255) ? -EINVAL
: 382 (scancode
<128) ? high_keys
[scancode
- SC_LIM
] : 383 e0_keys
[scancode
-128]; 386 voidsunkbd_inchar(unsigned char ch
,struct pt_regs
*regs
); 387 static voidkeyboard_timer(unsigned long ignored
); 389 static struct timer_list
390 auto_repeat_timer
= { NULL
, NULL
,0,0, keyboard_timer
}; 392 /* Keeps track of the last pressed key */ 393 static unsigned char last_keycode
; 396 keyboard_timer(unsigned long ignored
) 400 save_flags(flags
);cli(); 402 /* Auto repeat: send regs = 0 to indicate autorepeat */ 403 sunkbd_inchar(last_keycode
,0); 404 del_timer(&auto_repeat_timer
); 406 auto_repeat_timer
.expires
= jiffies
+ kbd_rate_ticks
; 407 add_timer(&auto_repeat_timer
); 409 restore_flags(flags
); 412 /* #define SKBD_DEBUG */ 413 /* This is our keyboard 'interrupt' routine. */ 414 voidsunkbd_inchar(unsigned char ch
,struct pt_regs
*regs
) 416 unsigned char keycode
; 417 char up_flag
;/* 0 or SUNKBD_UBIT */ 420 if(ch
== SKBD_RESET
) { 421 kbd_reset_pending
=1; 424 if(ch
== SKBD_LYOUT
) { 425 kbd_layout_pending
=1; 428 if(kbd_reset_pending
) { 430 kbd_reset_pending
=0; 431 if(ch
== SUNKBD_TYPE4
) 432 send_cmd(SKBDCMD_GLAYOUT
); 434 }else if(kbd_layout_pending
) { 436 kbd_layout_pending
=0; 438 }else if(ch
== SKBD_ALLUP
) { 439 del_timer(&auto_repeat_timer
); 440 memset(key_down
,0,sizeof(key_down
)); 441 compute_shiftstate(); 446 printk("KBD<ALL KEYS UP>"); 448 printk("KBD<%x %s>", ch
, 449 ((ch
&0x80) ?"UP":"DOWN")); 452 /* Whee, a real character. */ 455 last_keycode
= keycode
= ch
; 459 add_keyboard_randomness(keycode
); 461 mark_bh(KEYBOARD_BH
); 462 do_poke_blanked_console
=1; 464 kbd
= kbd_table
+ fg_console
; 465 tty
= ttytab
[fg_console
]; 466 if((raw_mode
= (kbd
->kbdmode
== VC_RAW
))) { 467 if(kbd_redirected
== fg_console
+1) 471 /* we do not return yet, because we want to maintain 472 * the key_down array, so that we have the correct 473 * values when finishing RAW mode or when changing VT's. 476 up_flag
= (keycode
& SUNKBD_UBIT
);/* The 'up' bit */ 477 keycode
&= SUNKBD_KMASK
;/* all the rest */ 478 del_timer(&auto_repeat_timer
); 481 clear_bit(keycode
, key_down
); 483 if(!norepeat_keys
[keycode
]) { 485 auto_repeat_timer
.expires
= 486 jiffies
+ kbd_delay_ticks
; 487 add_timer(&auto_repeat_timer
); 490 rep
=set_bit(keycode
, key_down
); 496 if(kbd
->kbdmode
== VC_MEDIUMRAW
) { 497 put_queue(keycode
+ up_flag
); 502 * Small change in philosophy: earlier we defined repetition by 503 * rep = keycode == prev_keycode; 504 * prev_keycode = keycode; 505 * but now by the fact that the depressed key was down already. 506 * Does this ever make a difference? Yes. 510 * Repeat a key only if the input buffers are empty or the 511 * characters get echoed locally. This makes key repeat usable 512 * with slow applications and under heavy loads. 515 (vc_kbd_mode(kbd
,VC_REPEAT
) && tty
&& 516 (L_ECHO(tty
) || (tty
->driver
.chars_in_buffer(tty
) ==0)))) { 520 /* the XOR below used to be an OR */ 521 int shift_final
= shift_state
^ kbd
->lockstate
; 522 ushort
*key_map
= key_maps
[shift_final
]; 524 if(key_map
!= NULL
) { 525 keysym
= key_map
[keycode
]; 530 if(type
== KT_LETTER
) { 532 if(vc_kbd_led(kbd
, VC_CAPSLOCK
)) { 533 key_map
= key_maps
[shift_final
^ (1<<KG_SHIFT
)]; 535 keysym
= key_map
[keycode
]; 538 (*key_handler
[type
])(keysym
&0xff, up_flag
); 544 /* we have at least to update shift_state */ 545 compute_shiftstate(); 550 static voidput_queue(int ch
) 552 wake_up(&keypress_wait
); 554 tty_insert_flip_char(tty
, ch
,0); 555 tty_schedule_flip(tty
); 559 static voidputs_queue(char*cp
) 561 wake_up(&keypress_wait
); 566 tty_insert_flip_char(tty
, *cp
,0); 569 tty_schedule_flip(tty
); 572 static voidapplkey(int key
,char mode
) 574 static char buf
[] = {0x1b,'O',0x00,0x00}; 576 buf
[1] = (mode
?'O':'['); 581 static voidenter(void) 584 if(vc_kbd_mode(kbd
,VC_CRLF
)) 588 static voidcaps_toggle(void) 592 chg_vc_kbd_led(kbd
, VC_CAPSLOCK
); 595 static voidcaps_on(void) 599 set_vc_kbd_led(kbd
, VC_CAPSLOCK
); 602 static voidshow_ptregs(void) 608 static voidhold(void) 614 * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty); 615 * these routines are also activated by ^S/^Q. 616 * (And SCROLLOCK can also be set by the ioctl KDSKBLED.) 626 if(vc_kbd_mode(kbd
,VC_APPLIC
)) 633 * Bind this to Shift-NumLock if you work in application keypad mode 634 * but want to be able to change the NumLock flag. 635 * Bind this to NumLock if you prefer that the NumLock key always 636 * changes the NumLock flag. 638 static voidbare_num(void) 641 chg_vc_kbd_led(kbd
,VC_NUMLOCK
); 644 static voidlastcons(void) 646 /* switch to the last used console, ChN */ 647 set_console(last_console
); 650 static voiddecr_console(void) 654 for(i
= fg_console
-1; i
!= fg_console
; i
--) { 656 i
= MAX_NR_CONSOLES
-1; 657 if(vc_cons_allocated(i
)) 663 static voidincr_console(void) 667 for(i
= fg_console
+1; i
!= fg_console
; i
++) { 668 if(i
== MAX_NR_CONSOLES
) 670 if(vc_cons_allocated(i
)) 676 static voidsend_intr(void) 680 tty_insert_flip_char(tty
,0, TTY_BREAK
); 681 tty_schedule_flip(tty
); 684 static voidscroll_forw(void) 689 static voidscroll_back(void) 694 static voidboot_it(void) 696 externintobp_system_intr(void); 698 if(!obp_system_intr()) 700 /* sigh.. attempt to prevent multiple entry */ 705 static voidcompose(void) 712 int spawnpid
, spawnsig
; 714 static voidspawn_console(void) 717 if(kill_proc(spawnpid
, spawnsig
,1)) 726 * Need to fix SAK handling to fix up RAW/MEDIUM_RAW and 727 * vt_cons modes before we can enable RAW/MEDIUM_RAW SAK 730 * We should do this some day --- the whole point of a secure 731 * attention key is that it should be guaranteed to always 734 reset_vc(fg_console
); 735 do_unblank_screen();/* not in interrupt routine? */ 739 static voiddo_ignore(unsigned char value
,char up_flag
) 745 compute_shiftstate(); 748 static voiddo_spec(unsigned char value
,char up_flag
) 752 if(value
>=SIZE(spec_fn_table
)) 754 spec_fn_table
[value
](); 757 static voiddo_lowercase(unsigned char value
,char up_flag
) 759 printk("keyboard.c: do_lowercase was called - impossible\n"); 762 static voiddo_self(unsigned char value
,char up_flag
) 765 return;/* no action, if this is a key release */ 768 value
=handle_diacr(value
); 788 static unsigned char ret_diacr
[NR_DEAD
] = 789 {A_GRAVE
, A_ACUTE
, A_CFLEX
, A_TILDE
, A_DIAER
, A_CEDIL
}; 791 /* If a dead key pressed twice, output a character corresponding to it, */ 792 /* otherwise just remember the dead key. */ 794 static voiddo_dead(unsigned char value
,char up_flag
) 799 value
= ret_diacr
[value
]; 800 if(diacr
== value
) {/* pressed twice */ 809 /* If space is pressed, return the character corresponding the pending */ 810 /* dead key, otherwise try to combine the two. */ 812 unsigned charhandle_diacr(unsigned char ch
) 821 for(i
=0; i
< accent_table_size
; i
++) { 822 if(accent_table
[i
].diacr
== d
&& accent_table
[i
].base
== ch
) 823 return accent_table
[i
].result
; 830 static voiddo_cons(unsigned char value
,char up_flag
) 837 static voiddo_fn(unsigned char value
,char up_flag
) 841 if(value
<SIZE(func_table
)) { 842 if(func_table
[value
]) 843 puts_queue(func_table
[value
]); 845 printk("do_fn called with value=%d\n", value
); 848 static voiddo_pad(unsigned char value
,char up_flag
) 850 static const char*pad_chars
="0123456789+-*/\015,.?"; 851 static const char*app_map
="pqrstuvwxylSRQMnn?"; 854 return;/* no action, if this is a key release */ 856 /* kludge... shift forces cursor/number keys */ 857 if(vc_kbd_mode(kbd
,VC_APPLIC
) && !k_down
[KG_SHIFT
]) { 858 applkey(app_map
[value
],1); 862 if(!vc_kbd_led(kbd
,VC_NUMLOCK
)) 866 do_fn(KVAL(K_REMOVE
),0); 869 do_fn(KVAL(K_INSERT
),0); 872 do_fn(KVAL(K_SELECT
),0); 875 do_cur(KVAL(K_DOWN
),0); 878 do_fn(KVAL(K_PGDN
),0); 881 do_cur(KVAL(K_LEFT
),0); 884 do_cur(KVAL(K_RIGHT
),0); 887 do_fn(KVAL(K_FIND
),0); 890 do_cur(KVAL(K_UP
),0); 893 do_fn(KVAL(K_PGUP
),0); 896 applkey('G',vc_kbd_mode(kbd
, VC_APPLIC
)); 900 put_queue(pad_chars
[value
]); 901 if(value
==KVAL(K_PENTER
) &&vc_kbd_mode(kbd
, VC_CRLF
)) 905 static voiddo_cur(unsigned char value
,char up_flag
) 907 static const char*cur_chars
="BDCA"; 911 applkey(cur_chars
[value
],vc_kbd_mode(kbd
,VC_CKMODE
)); 914 static voiddo_shift(unsigned char value
,char up_flag
) 916 int old_state
= shift_state
; 922 a CapsShift key acts like Shift but undoes CapsLock */ 923 if(value
==KVAL(K_CAPSSHIFT
)) { 924 value
=KVAL(K_SHIFT
); 926 clr_vc_kbd_led(kbd
, VC_CAPSLOCK
); 930 /* handle the case that two shift or control 931 keys are depressed simultaneously */ 938 shift_state
|= (1<< value
); 940 shift_state
&= ~ (1<< value
); 942 /* kludge, no joke... */ 943 if(up_flag
&& shift_state
!= old_state
&& npadch
!= -1) { 944 put_queue(npadch
&0xff); 949 /* called after returning from RAW mode or when changing consoles - 950 recompute k_down[] and shift_state from key_down[] */ 951 /* maybe called when keymap is undefined, so that shiftkey release is seen */ 952 voidcompute_shiftstate(void) 954 int i
, j
, k
, sym
, val
; 957 for(i
=0; i
<SIZE(k_down
); i
++) 960 for(i
=0; i
<SIZE(key_down
); i
++) 961 if(key_down
[i
]) {/* skip this word if not a single bit on */ 963 for(j
=0; j
<BITS_PER_LONG
; j
++,k
++) 964 if(test_bit(k
, key_down
)) { 965 sym
=U(plain_map
[k
]); 966 if(KTYP(sym
) == KT_SHIFT
) { 968 if(val
==KVAL(K_CAPSSHIFT
)) 971 shift_state
|= (1<<val
); 977 static voiddo_meta(unsigned char value
,char up_flag
) 982 if(vc_kbd_mode(kbd
, VC_META
)) { 986 put_queue(value
|0x80); 989 static voiddo_ascii(unsigned char value
,char up_flag
) 996 if(value
<10)/* decimal input of code, while Alt depressed */ 998 else{/* hexadecimal input of code, while AltGr depressed */ 1006 npadch
= npadch
* base
+ value
; 1009 static voiddo_lock(unsigned char value
,char up_flag
) 1013 chg_vc_kbd_lock(kbd
, value
); 1017 * The leds display either (i) the status of NumLock, CapsLock, ScrollLock, 1018 * or (ii) whatever pattern of lights people want to show using KDSETLED, 1019 * or (iii) specified bits of specified words in kernel memory. 1022 static unsigned char ledstate
=0xff;/* undefined */ 1023 static unsigned char sunkbd_ledstate
=0xff;/* undefined */ 1024 static unsigned char ledioctl
; 1026 unsigned chargetledstate(void) { 1030 voidsetledstate(struct kbd_struct
*kbd
,unsigned int led
) { 1033 kbd
->ledmode
= LED_SHOW_IOCTL
; 1035 kbd
->ledmode
= LED_SHOW_FLAGS
; 1039 static struct ledptr
{ 1042 unsigned char valid
:1; 1045 voidregister_leds(int console
,unsigned int led
, 1046 unsigned int*addr
,unsigned int mask
) { 1047 struct kbd_struct
*kbd
= kbd_table
+ console
; 1049 ledptrs
[led
].addr
= addr
; 1050 ledptrs
[led
].mask
= mask
; 1051 ledptrs
[led
].valid
=1; 1052 kbd
->ledmode
= LED_SHOW_MEM
; 1054 kbd
->ledmode
= LED_SHOW_FLAGS
; 1057 staticinlineunsigned chargetleds(void){ 1058 struct kbd_struct
*kbd
= kbd_table
+ fg_console
; 1061 if(kbd
->ledmode
== LED_SHOW_IOCTL
) 1063 leds
= kbd
->ledflagstate
; 1064 if(kbd
->ledmode
== LED_SHOW_MEM
) { 1065 if(ledptrs
[0].valid
) { 1066 if(*ledptrs
[0].addr
& ledptrs
[0].mask
) 1071 if(ledptrs
[1].valid
) { 1072 if(*ledptrs
[1].addr
& ledptrs
[1].mask
) 1077 if(ledptrs
[2].valid
) { 1078 if(*ledptrs
[2].addr
& ledptrs
[2].mask
) 1088 * This routine is the bottom half of the keyboard interrupt 1089 * routine, and runs with all interrupts enabled. It does 1090 * console changing, led setting and copy_to_cooked, which can 1091 * take a reasonably long time. 1093 * Aside from timing (which isn't really that important for 1094 * keyboard interrupts as they happen often), using the software 1095 * interrupt routines for this thing allows us to easily mask 1096 * this when we don't want any of the above to happen. Not yet 1097 * used, but this allows for easy and efficient race-condition 1098 * prevention later on. 1100 static voidkbd_bh(void) 1102 unsigned char leds
=getleds(); 1103 unsigned char kbd_leds
=vcleds_to_sunkbd(leds
); 1105 if(kbd_leds
!= sunkbd_ledstate
) { 1107 sunkbd_ledstate
= kbd_leds
; 1108 send_cmd(SKBDCMD_SETLED
); 1113 /* Support for keyboard "beeps". */ 1115 /* Timer routine to turn off the beep after the interval expires. */ 1116 static voidsunkbd_kd_nosound(unsigned long __unused
) 1118 send_cmd(SKBDCMD_BELLOFF
); 1122 * Initiate a keyboard beep. If the frequency is zero, then we stop 1123 * the beep. Any other frequency will start a monotone beep. The beep 1124 * will be stopped by a timer after "ticks" jiffies. If ticks is 0, 1125 * then we do not start a timer. 1127 static voidsunkbd_kd_mksound(unsigned int hz
,unsigned int ticks
) 1129 unsigned long flags
; 1130 static struct timer_list sound_timer
= { NULL
, NULL
,0,0, 1131 sunkbd_kd_nosound
}; 1136 del_timer(&sound_timer
); 1139 send_cmd(SKBDCMD_BELLON
); 1141 sound_timer
.expires
= jiffies
+ ticks
; 1142 add_timer(&sound_timer
); 1145 send_cmd(SKBDCMD_BELLOFF
); 1147 restore_flags(flags
); 1150 externvoid(*kd_mksound
)(unsigned int hz
,unsigned int ticks
); 1155 struct kbd_struct kbd0
; 1156 externstruct tty_driver console_driver
; 1158 kbd0
.ledflagstate
= kbd0
.default_ledflagstate
= KBD_DEFLEDS
; 1159 kbd0
.ledmode
= LED_SHOW_FLAGS
; 1160 kbd0
.lockstate
= KBD_DEFLOCK
; 1161 kbd0
.modeflags
= KBD_DEFMODE
; 1162 kbd0
.kbdmode
= VC_XLATE
; 1164 for(i
=0; i
< MAX_NR_CONSOLES
; i
++) 1165 kbd_table
[i
] = kbd0
; 1167 ttytab
= console_driver
.table
; 1169 kd_mksound
= sunkbd_kd_mksound
; 1171 /* XXX Check keyboard-click? property in 'options' PROM node XXX */ 1172 if(sparc_cpu_model
!= sun4
) { 1173 opt_node
=prom_getchild(prom_root_node
); 1174 opt_node
=prom_searchsiblings(opt_node
,"options"); 1175 i
=prom_getintdefault(opt_node
,"keyboard-click?", -1); 1183 init_bh(KEYBOARD_BH
, kbd_bh
); 1184 mark_bh(KEYBOARD_BH
); 1188 /* /dev/kbd support */ 1190 #define KBD_QSIZE 32 1191 static Firm_event kbd_queue
[KBD_QSIZE
]; 1192 static int kbd_head
, kbd_tail
; 1194 static int kbd_active
=0; 1195 static struct wait_queue
*kbd_wait
; 1196 static struct fasync_struct
*kb_fasync
; 1201 int next
= (kbd_head
+1) % KBD_QSIZE
; 1203 if(scan
== KBD_IDLE
) 1205 if(next
!= kbd_tail
){ 1206 kbd_queue
[kbd_head
].id
= scan
& KBD_KEYMASK
; 1207 kbd_queue
[kbd_head
].value
=scan
& KBD_UP
? VKEY_UP
: VKEY_DOWN
; 1208 kbd_queue
[kbd_head
].time
= xtime
; 1212 kill_fasync(kb_fasync
, SIGIO
); 1213 wake_up_interruptible(&kbd_wait
); 1217 kbd_read(struct inode
*inode
,struct file
*f
,char*buffer
,unsigned long count
) 1219 struct wait_queue wait
= { current
, NULL
}; 1222 /* Return EWOULDBLOCK, because this is what the X server expects */ 1223 if(kbd_head
== kbd_tail
){ 1224 if(f
->f_flags
& O_NONBLOCK
) 1226 add_wait_queue(&kbd_wait
, &wait
); 1227 while(kbd_head
== kbd_tail
&& !(current
->signal
& ~current
->blocked
)){ 1228 current
->state
= TASK_INTERRUPTIBLE
; 1231 current
->state
= TASK_RUNNING
; 1232 remove_wait_queue(&kbd_wait
, &wait
); 1234 /* There is data in the keyboard, fill the user buffer */ 1237 for(; p
< end
&& kbd_head
!= kbd_tail
; p
+=sizeof(Firm_event
)){ 1238 copy_to_user_ret((Firm_event
*)p
, &kbd_queue
[kbd_tail
],sizeof(Firm_event
), -EFAULT
); 1240 printk("[%s]", kbd_queue
[kbd_tail
].value
== VKEY_UP
?"UP":"DOWN"); 1243 kbd_tail
%= KBD_QSIZE
; 1250 kbd_fasync(struct inode
*inode
,struct file
*filp
,int on
) 1254 retval
=fasync_helper(inode
, filp
, on
, &kb_fasync
); 1260 static unsigned intkbd_poll(struct file
*f
, poll_table
*wait
) 1262 poll_wait(&kbd_wait
, wait
); 1263 if(kbd_head
!= kbd_tail
) 1264 return POLLIN
| POLLRDNORM
; 1269 kbd_ioctl(struct inode
*i
,struct file
*f
,unsigned int cmd
,unsigned long arg
) 1272 unsigned char leds
=0; 1276 case KIOCTYPE
:/* return keyboard type */ 1277 put_user_ret(sunkbd_type
, (int*) arg
, -EFAULT
); 1280 put_user_ret(TR_UNTRANS_EVENT
, (int*) arg
, -EFAULT
); 1283 get_user_ret(value
, (int*) arg
, -EFAULT
); 1284 if(value
!= TR_UNTRANS_EVENT
) 1288 put_user_ret(sunkbd_layout
, (int*) arg
, -EFAULT
); 1291 #ifndef CODING_NEW_DRIVER 1292 get_user_ret(value
, (int*) arg
, -EFAULT
); 1294 kbd_redirected
= fg_console
+1; 1297 kbd_table
[fg_console
].kbdmode
= kbd_redirected
? VC_RAW
: VC_XLATE
; 1301 get_user_ret(value
, (int*) arg
, -EFAULT
); 1302 c
= (unsigned char) value
; 1305 case SKBDCMD_NOCLICK
: 1308 case SKBDCMD_BELLON
: 1311 case SKBDCMD_BELLOFF
: 1318 get_user_ret(c
, (unsigned char*) arg
, -EFAULT
); 1320 if(c
& LED_SCRLCK
) leds
|= (1<< VC_SCROLLOCK
); 1321 if(c
& LED_NLOCK
) leds
|= (1<< VC_NUMLOCK
); 1322 if(c
& LED_CLOCK
) leds
|= (1<< VC_CAPSLOCK
); 1323 compose_led_on
= !!(c
& LED_CMPOSE
); 1324 setledstate(kbd_table
+ fg_console
, leds
); 1327 put_user_ret(vcleds_to_sunkbd(getleds()), (unsigned char*) arg
, -EFAULT
); 1331 struct kbd_rate rate
; 1333 rate
.delay
= kbd_delay_ticks
; 1335 rate
.rate
= HZ
/ kbd_rate_ticks
; 1339 copy_to_user_ret((struct kbd_rate
*)arg
, &rate
, 1340 sizeof(struct kbd_rate
), -EFAULT
); 1346 struct kbd_rate rate
; 1348 if(verify_area(VERIFY_READ
, (void*)arg
, 1349 sizeof(struct kbd_rate
))) 1351 copy_from_user(&rate
, (struct kbd_rate
*)arg
, 1352 sizeof(struct kbd_rate
)); 1359 kbd_rate_ticks
= HZ
/ rate
.rate
; 1360 kbd_delay_ticks
= rate
.delay
; 1364 case FIONREAD
:/* return number of bytes in kbd queue */ 1368 count
= kbd_head
- kbd_tail
; 1369 put_user_ret((count
<0) ? KBD_QSIZE
- count
: count
, (int*) arg
, -EFAULT
); 1373 printk("Unknown Keyboard ioctl: %8.8x\n", cmd
); 1380 kbd_open(struct inode
*i
,struct file
*f
) 1387 kbd_opened
= fg_console
+1; 1388 kbd_head
= kbd_tail
=0; 1393 kbd_close(struct inode
*i
,struct file
*f
) 1399 kbd_table
[kbd_opened
-1].kbdmode
= VC_XLATE
; 1409 file_operations kbd_fops
= 1416 kbd_ioctl
,/* ioctl */ 1419 kbd_close
,/* close */ 1421 kbd_fasync
,/* fasync */ 1422 NULL
,/* check_media_change */ 1423 NULL
,/* revalidate */ 1426 __initfunc(voidkeyboard_zsinit(void)) 1430 /* Test out the leds */ 1432 send_cmd(SKBDCMD_RESET
); 1433 while((sunkbd_type
==255) && timeout
<500000) { 1438 if(timeout
>=500000) { 1439 printk("keyboard: not present\n"); 1443 if(sunkbd_type
!= SUNKBD_TYPE4
) { 1444 printk("Sun TYPE %d keyboard detected ", sunkbd_type
); 1448 while(timeout
++ <500000) 1450 printk("Sun TYPE %d keyboard detected ", 1451 ((sunkbd_layout
& SUNKBD_LOUT_TYP5_MASK
) ?5:4)); 1453 if(sunkbd_type
== SUNKBD_TYPE2
) 1457 send_cmd(SKBDCMD_CLICK
); 1458 printk("with keyclick\n"); 1460 send_cmd(SKBDCMD_NOCLICK
); 1461 printk("without keyclick\n"); 1464 /* Dork with led lights, then turn them all off */ 1465 send_cmd(SKBDCMD_SETLED
);send_cmd(0xf);/* All on */ 1466 send_cmd(SKBDCMD_SETLED
);send_cmd(0x0);/* All off */ 1468 /* Register the /dev/kbd interface */ 1469 if(register_chrdev(KBD_MAJOR
,"kbd", &kbd_fops
)){ 1470 printk("Could not register /dev/kbd device\n");