blob: e2011669c7bb4bc187a3e216e21a37b1711b9f4e [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/char/keyboard.c
3 *
4 * Written for linux by Johan Myreen as a translation from
5 * the assembly version by Linus (with diacriticals added)
6 *
7 * Some additional features added by Christoph Niemann (ChN), March 1993
8 *
9 * Loadable keymaps by Risto Kankkunen, May 1993
10 *
11 * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
12 * Added decr/incr_console, dynamic keymaps, Unicode support,
13 * dynamic function/string keys, led setting, Sept 1994
14 * `Sticky' modifier keys, 951006.
15 *
16 * 11-11-96: SAK should now work in the raw mode (Martin Mares)
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -050017 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 * Modified to provide 'generic' keyboard support by Hamish Macdonald
19 * Merge with the m68k keyboard driver and split-off of the PC low-level
20 * parts by Geert Uytterhoeven, May 1997
21 *
22 * 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
23 * 30-07-98: Dead keys redone, aeb@cwi.nl.
24 * 21-08-02: Converted to input API, major cleanup. (Vojtech Pavlik)
25 */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28#include <linux/sched.h>
29#include <linux/tty.h>
30#include <linux/tty_flip.h>
31#include <linux/mm.h>
32#include <linux/string.h>
33#include <linux/init.h>
34#include <linux/slab.h>
35
36#include <linux/kbd_kern.h>
37#include <linux/kbd_diacr.h>
38#include <linux/vt_kern.h>
39#include <linux/sysrq.h>
40#include <linux/input.h>
Adrian Bunk83cc5ed2006-06-25 05:47:41 -070041#include <linux/reboot.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
43static void kbd_disconnect(struct input_handle *handle);
44extern void ctrl_alt_del(void);
45
46/*
47 * Exported functions/variables
48 */
49
50#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
51
52/*
53 * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
54 * This seems a good reason to start with NumLock off. On HIL keyboards
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -050055 * of PARISC machines however there is no NumLock key and everyone expects the keypad
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 * to be used for numbers.
57 */
58
59#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
60#define KBD_DEFLEDS (1 << VC_NUMLOCK)
61#else
62#define KBD_DEFLEDS 0
63#endif
64
65#define KBD_DEFLOCK 0
66
67void compute_shiftstate(void);
68
69/*
70 * Handler Tables.
71 */
72
73#define K_HANDLERS\
74 k_self, k_fn, k_spec, k_pad,\
75 k_dead, k_cons, k_cur, k_shift,\
76 k_meta, k_ascii, k_lock, k_lowercase,\
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -050077 k_slock, k_dead2, k_brl, k_ignore
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -050079typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
Linus Torvalds1da177e2005-04-16 15:20:36 -070080 char up_flag, struct pt_regs *regs);
81static k_handler_fn K_HANDLERS;
82static k_handler_fn *k_handler[16] = { K_HANDLERS };
83
84#define FN_HANDLERS\
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -050085 fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
86 fn_show_state, fn_send_intr, fn_lastcons, fn_caps_toggle,\
87 fn_num, fn_hold, fn_scroll_forw, fn_scroll_back,\
88 fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\
89 fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
91typedef void (fn_handler_fn)(struct vc_data *vc, struct pt_regs *regs);
92static fn_handler_fn FN_HANDLERS;
93static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
94
95/*
96 * Variables exported for vt_ioctl.c
97 */
98
99/* maximum values each key_handler can handle */
100const int max_vals[] = {
101 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
102 NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500103 255, NR_LOCK - 1, 255, NR_BRL - 1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104};
105
106const int NR_TYPES = ARRAY_SIZE(max_vals);
107
108struct kbd_struct kbd_table[MAX_NR_CONSOLES];
109static struct kbd_struct *kbd = kbd_table;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
Eric W. Biederman81af8d62006-10-02 02:17:13 -0700111struct vt_spawn_console vt_spawn_con = {
112 .lock = SPIN_LOCK_UNLOCKED,
113 .pid = NULL,
114 .sig = 0,
115};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116
117/*
118 * Variables exported for vt.c
119 */
120
121int shift_state = 0;
122
123/*
124 * Internal Data.
125 */
126
127static struct input_handler kbd_handler;
128static unsigned long key_down[NBITS(KEY_MAX)]; /* keyboard key bitmap */
129static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
130static int dead_key_next;
131static int npadch = -1; /* -1 or number assembled on pad */
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500132static unsigned int diacr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133static char rep; /* flag telling character repeat */
134
135static unsigned char ledstate = 0xff; /* undefined */
136static unsigned char ledioctl;
137
138static struct ledptr {
139 unsigned int *addr;
140 unsigned int mask;
141 unsigned char valid:1;
142} ledptrs[3];
143
144/* Simple translation table for the SysRq keys */
145
146#ifdef CONFIG_MAGIC_SYSRQ
147unsigned char kbd_sysrq_xlate[KEY_MAX + 1] =
148 "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
149 "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
150 "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
151 "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
152 "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
153 "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
154 "\r\000/"; /* 0x60 - 0x6f */
155static int sysrq_down;
Fredrik Roubertd2be8ee2006-06-26 00:24:35 -0700156static int sysrq_alt_use;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157#endif
158static int sysrq_alt;
159
160/*
161 * Translation of scancodes to keycodes. We set them on only the first attached
162 * keyboard - for per-keyboard setting, /dev/input/event is more useful.
163 */
164int getkeycode(unsigned int scancode)
165{
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500166 struct list_head *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 struct input_dev *dev = NULL;
168
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500169 list_for_each(node, &kbd_handler.h_list) {
170 struct input_handle *handle = to_handle_h(node);
171 if (handle->dev->keycodesize) {
172 dev = handle->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 break;
174 }
175 }
176
177 if (!dev)
178 return -ENODEV;
179
180 if (scancode >= dev->keycodemax)
181 return -EINVAL;
182
183 return INPUT_KEYCODE(dev, scancode);
184}
185
186int setkeycode(unsigned int scancode, unsigned int keycode)
187{
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500188 struct list_head *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 struct input_dev *dev = NULL;
190 unsigned int i, oldkey;
191
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500192 list_for_each(node, &kbd_handler.h_list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193 struct input_handle *handle = to_handle_h(node);
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500194 if (handle->dev->keycodesize) {
195 dev = handle->dev;
196 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 }
198 }
199
200 if (!dev)
201 return -ENODEV;
202
203 if (scancode >= dev->keycodemax)
204 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 if (keycode < 0 || keycode > KEY_MAX)
206 return -EINVAL;
Ian Campbell4cee9952005-09-04 01:41:14 -0500207 if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
Vojtech Pavlik5ac7ba32005-07-24 00:50:03 -0500208 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209
210 oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode);
211
212 clear_bit(oldkey, dev->keybit);
213 set_bit(keycode, dev->keybit);
214
215 for (i = 0; i < dev->keycodemax; i++)
216 if (INPUT_KEYCODE(dev,i) == oldkey)
217 set_bit(oldkey, dev->keybit);
218
219 return 0;
220}
221
222/*
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500223 * Making beeps and bells.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 */
225static void kd_nosound(unsigned long ignored)
226{
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500227 struct list_head *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
Dmitry Torokhov0e739d22006-07-06 00:22:43 -0400229 list_for_each(node, &kbd_handler.h_list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 struct input_handle *handle = to_handle_h(node);
231 if (test_bit(EV_SND, handle->dev->evbit)) {
232 if (test_bit(SND_TONE, handle->dev->sndbit))
Dmitry Torokhov0e739d22006-07-06 00:22:43 -0400233 input_inject_event(handle, EV_SND, SND_TONE, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 if (test_bit(SND_BELL, handle->dev->sndbit))
Dmitry Torokhov0e739d22006-07-06 00:22:43 -0400235 input_inject_event(handle, EV_SND, SND_BELL, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 }
237 }
238}
239
Ingo Molnar8d06afa2005-09-09 13:10:40 -0700240static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241
242void kd_mksound(unsigned int hz, unsigned int ticks)
243{
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500244 struct list_head *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245
246 del_timer(&kd_mksound_timer);
247
248 if (hz) {
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500249 list_for_each_prev(node, &kbd_handler.h_list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 struct input_handle *handle = to_handle_h(node);
251 if (test_bit(EV_SND, handle->dev->evbit)) {
252 if (test_bit(SND_TONE, handle->dev->sndbit)) {
Dmitry Torokhov0e739d22006-07-06 00:22:43 -0400253 input_inject_event(handle, EV_SND, SND_TONE, hz);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 break;
255 }
256 if (test_bit(SND_BELL, handle->dev->sndbit)) {
Dmitry Torokhov0e739d22006-07-06 00:22:43 -0400257 input_inject_event(handle, EV_SND, SND_BELL, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 break;
259 }
260 }
261 }
262 if (ticks)
263 mod_timer(&kd_mksound_timer, jiffies + ticks);
264 } else
265 kd_nosound(0);
266}
267
268/*
269 * Setting the keyboard rate.
270 */
271
272int kbd_rate(struct kbd_repeat *rep)
273{
274 struct list_head *node;
275 unsigned int d = 0;
276 unsigned int p = 0;
277
Dmitry Torokhov0e739d22006-07-06 00:22:43 -0400278 list_for_each(node, &kbd_handler.h_list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 struct input_handle *handle = to_handle_h(node);
280 struct input_dev *dev = handle->dev;
281
282 if (test_bit(EV_REP, dev->evbit)) {
283 if (rep->delay > 0)
Dmitry Torokhov0e739d22006-07-06 00:22:43 -0400284 input_inject_event(handle, EV_REP, REP_DELAY, rep->delay);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 if (rep->period > 0)
Dmitry Torokhov0e739d22006-07-06 00:22:43 -0400286 input_inject_event(handle, EV_REP, REP_PERIOD, rep->period);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700287 d = dev->rep[REP_DELAY];
288 p = dev->rep[REP_PERIOD];
289 }
290 }
291 rep->delay = d;
292 rep->period = p;
293 return 0;
294}
295
296/*
297 * Helper Functions.
298 */
299static void put_queue(struct vc_data *vc, int ch)
300{
301 struct tty_struct *tty = vc->vc_tty;
302
303 if (tty) {
304 tty_insert_flip_char(tty, ch, 0);
305 con_schedule_flip(tty);
306 }
307}
308
309static void puts_queue(struct vc_data *vc, char *cp)
310{
311 struct tty_struct *tty = vc->vc_tty;
312
313 if (!tty)
314 return;
315
316 while (*cp) {
317 tty_insert_flip_char(tty, *cp, 0);
318 cp++;
319 }
320 con_schedule_flip(tty);
321}
322
323static void applkey(struct vc_data *vc, int key, char mode)
324{
325 static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
326
327 buf[1] = (mode ? 'O' : '[');
328 buf[2] = key;
329 puts_queue(vc, buf);
330}
331
332/*
333 * Many other routines do put_queue, but I think either
334 * they produce ASCII, or they produce some user-assigned
335 * string, and in both cases we might assume that it is
336 * in utf-8 already. UTF-8 is defined for words of up to 31 bits,
337 * but we need only 16 bits here
338 */
339static void to_utf8(struct vc_data *vc, ushort c)
340{
341 if (c < 0x80)
342 /* 0******* */
343 put_queue(vc, c);
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500344 else if (c < 0x800) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 /* 110***** 10****** */
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500346 put_queue(vc, 0xc0 | (c >> 6));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 put_queue(vc, 0x80 | (c & 0x3f));
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500348 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 /* 1110**** 10****** 10****** */
350 put_queue(vc, 0xe0 | (c >> 12));
351 put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
352 put_queue(vc, 0x80 | (c & 0x3f));
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500353 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354}
355
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500356/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 * Called after returning from RAW mode or when changing consoles - recompute
358 * shift_down[] and shift_state from key_down[] maybe called when keymap is
359 * undefined, so that shiftkey release is seen
360 */
361void compute_shiftstate(void)
362{
363 unsigned int i, j, k, sym, val;
364
365 shift_state = 0;
366 memset(shift_down, 0, sizeof(shift_down));
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500367
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 for (i = 0; i < ARRAY_SIZE(key_down); i++) {
369
370 if (!key_down[i])
371 continue;
372
373 k = i * BITS_PER_LONG;
374
375 for (j = 0; j < BITS_PER_LONG; j++, k++) {
376
377 if (!test_bit(k, key_down))
378 continue;
379
380 sym = U(key_maps[0][k]);
381 if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
382 continue;
383
384 val = KVAL(sym);
385 if (val == KVAL(K_CAPSSHIFT))
386 val = KVAL(K_SHIFT);
387
388 shift_down[val]++;
389 shift_state |= (1 << val);
390 }
391 }
392}
393
394/*
395 * We have a combining character DIACR here, followed by the character CH.
396 * If the combination occurs in the table, return the corresponding value.
397 * Otherwise, if CH is a space or equals DIACR, return DIACR.
398 * Otherwise, conclude that DIACR was not combining after all,
399 * queue it and return CH.
400 */
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500401static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402{
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500403 unsigned int d = diacr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404 unsigned int i;
405
406 diacr = 0;
407
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500408 if ((d & ~0xff) == BRL_UC_ROW) {
409 if ((ch & ~0xff) == BRL_UC_ROW)
410 return d | ch;
411 } else {
412 for (i = 0; i < accent_table_size; i++)
413 if (accent_table[i].diacr == d && accent_table[i].base == ch)
414 return accent_table[i].result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 }
416
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500417 if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 return d;
419
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500420 if (kbd->kbdmode == VC_UNICODE)
421 to_utf8(vc, d);
422 else if (d < 0x100)
423 put_queue(vc, d);
424
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 return ch;
426}
427
428/*
429 * Special function handlers
430 */
431static void fn_enter(struct vc_data *vc, struct pt_regs *regs)
432{
433 if (diacr) {
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500434 if (kbd->kbdmode == VC_UNICODE)
435 to_utf8(vc, diacr);
436 else if (diacr < 0x100)
437 put_queue(vc, diacr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 diacr = 0;
439 }
440 put_queue(vc, 13);
441 if (vc_kbd_mode(kbd, VC_CRLF))
442 put_queue(vc, 10);
443}
444
445static void fn_caps_toggle(struct vc_data *vc, struct pt_regs *regs)
446{
447 if (rep)
448 return;
449 chg_vc_kbd_led(kbd, VC_CAPSLOCK);
450}
451
452static void fn_caps_on(struct vc_data *vc, struct pt_regs *regs)
453{
454 if (rep)
455 return;
456 set_vc_kbd_led(kbd, VC_CAPSLOCK);
457}
458
459static void fn_show_ptregs(struct vc_data *vc, struct pt_regs *regs)
460{
461 if (regs)
462 show_regs(regs);
463}
464
465static void fn_hold(struct vc_data *vc, struct pt_regs *regs)
466{
467 struct tty_struct *tty = vc->vc_tty;
468
469 if (rep || !tty)
470 return;
471
472 /*
473 * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
474 * these routines are also activated by ^S/^Q.
475 * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
476 */
477 if (tty->stopped)
478 start_tty(tty);
479 else
480 stop_tty(tty);
481}
482
483static void fn_num(struct vc_data *vc, struct pt_regs *regs)
484{
485 if (vc_kbd_mode(kbd,VC_APPLIC))
486 applkey(vc, 'P', 1);
487 else
488 fn_bare_num(vc, regs);
489}
490
491/*
492 * Bind this to Shift-NumLock if you work in application keypad mode
493 * but want to be able to change the NumLock flag.
494 * Bind this to NumLock if you prefer that the NumLock key always
495 * changes the NumLock flag.
496 */
497static void fn_bare_num(struct vc_data *vc, struct pt_regs *regs)
498{
499 if (!rep)
500 chg_vc_kbd_led(kbd, VC_NUMLOCK);
501}
502
503static void fn_lastcons(struct vc_data *vc, struct pt_regs *regs)
504{
505 /* switch to the last used console, ChN */
506 set_console(last_console);
507}
508
509static void fn_dec_console(struct vc_data *vc, struct pt_regs *regs)
510{
511 int i, cur = fg_console;
512
513 /* Currently switching? Queue this next switch relative to that. */
514 if (want_console != -1)
515 cur = want_console;
516
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500517 for (i = cur - 1; i != cur; i--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518 if (i == -1)
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500519 i = MAX_NR_CONSOLES - 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 if (vc_cons_allocated(i))
521 break;
522 }
523 set_console(i);
524}
525
526static void fn_inc_console(struct vc_data *vc, struct pt_regs *regs)
527{
528 int i, cur = fg_console;
529
530 /* Currently switching? Queue this next switch relative to that. */
531 if (want_console != -1)
532 cur = want_console;
533
534 for (i = cur+1; i != cur; i++) {
535 if (i == MAX_NR_CONSOLES)
536 i = 0;
537 if (vc_cons_allocated(i))
538 break;
539 }
540 set_console(i);
541}
542
543static void fn_send_intr(struct vc_data *vc, struct pt_regs *regs)
544{
545 struct tty_struct *tty = vc->vc_tty;
546
547 if (!tty)
548 return;
549 tty_insert_flip_char(tty, 0, TTY_BREAK);
550 con_schedule_flip(tty);
551}
552
553static void fn_scroll_forw(struct vc_data *vc, struct pt_regs *regs)
554{
555 scrollfront(vc, 0);
556}
557
558static void fn_scroll_back(struct vc_data *vc, struct pt_regs *regs)
559{
560 scrollback(vc, 0);
561}
562
563static void fn_show_mem(struct vc_data *vc, struct pt_regs *regs)
564{
565 show_mem();
566}
567
568static void fn_show_state(struct vc_data *vc, struct pt_regs *regs)
569{
570 show_state();
571}
572
573static void fn_boot_it(struct vc_data *vc, struct pt_regs *regs)
574{
575 ctrl_alt_del();
576}
577
578static void fn_compose(struct vc_data *vc, struct pt_regs *regs)
579{
580 dead_key_next = 1;
581}
582
583static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs)
584{
Eric W. Biederman81af8d62006-10-02 02:17:13 -0700585 spin_lock(&vt_spawn_con.lock);
586 if (vt_spawn_con.pid)
587 if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) {
588 put_pid(vt_spawn_con.pid);
589 vt_spawn_con.pid = NULL;
590 }
591 spin_unlock(&vt_spawn_con.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592}
593
594static void fn_SAK(struct vc_data *vc, struct pt_regs *regs)
595{
596 struct tty_struct *tty = vc->vc_tty;
597
598 /*
599 * SAK should also work in all raw modes and reset
600 * them properly.
601 */
602 if (tty)
603 do_SAK(tty);
604 reset_vc(vc);
605}
606
607static void fn_null(struct vc_data *vc, struct pt_regs *regs)
608{
609 compute_shiftstate();
610}
611
612/*
613 * Special key handlers
614 */
615static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
616{
617}
618
619static void k_spec(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
620{
621 if (up_flag)
622 return;
623 if (value >= ARRAY_SIZE(fn_handler))
624 return;
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500625 if ((kbd->kbdmode == VC_RAW ||
626 kbd->kbdmode == VC_MEDIUMRAW) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 value != KVAL(K_SAK))
628 return; /* SAK is allowed even in raw mode */
629 fn_handler[value](vc, regs);
630}
631
632static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
633{
634 printk(KERN_ERR "keyboard.c: k_lowercase was called - impossible\n");
635}
636
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500637static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag, struct pt_regs *regs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638{
639 if (up_flag)
640 return; /* no action, if this is a key release */
641
642 if (diacr)
643 value = handle_diacr(vc, value);
644
645 if (dead_key_next) {
646 dead_key_next = 0;
647 diacr = value;
648 return;
649 }
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500650 if (kbd->kbdmode == VC_UNICODE)
651 to_utf8(vc, value);
652 else if (value < 0x100)
653 put_queue(vc, value);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654}
655
656/*
657 * Handle dead key. Note that we now may have several
658 * dead keys modifying the same character. Very useful
659 * for Vietnamese.
660 */
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500661static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag, struct pt_regs *regs)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662{
663 if (up_flag)
664 return;
665 diacr = (diacr ? handle_diacr(vc, value) : value);
666}
667
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500668static void k_self(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
669{
670 k_unicode(vc, value, up_flag, regs);
671}
672
673static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
674{
675 k_deadunicode(vc, value, up_flag, regs);
676}
677
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678/*
679 * Obsolete - for backwards compatibility only
680 */
681static void k_dead(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
682{
Andreas Mohr0f5e5602006-06-05 00:18:00 -0400683 static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 value = ret_diacr[value];
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500685 k_deadunicode(vc, value, up_flag, regs);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686}
687
688static void k_cons(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
689{
690 if (up_flag)
691 return;
692 set_console(value);
693}
694
695static void k_fn(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
696{
697 unsigned v;
698
699 if (up_flag)
700 return;
701 v = value;
702 if (v < ARRAY_SIZE(func_table)) {
703 if (func_table[value])
704 puts_queue(vc, func_table[value]);
705 } else
706 printk(KERN_ERR "k_fn called with value=%d\n", value);
707}
708
709static void k_cur(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
710{
711 static const char *cur_chars = "BDCA";
712
713 if (up_flag)
714 return;
715 applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
716}
717
718static void k_pad(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
719{
Andreas Mohr0f5e5602006-06-05 00:18:00 -0400720 static const char pad_chars[] = "0123456789+-*/\015,.?()#";
721 static const char app_map[] = "pqrstuvwxylSRQMnnmPQS";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722
723 if (up_flag)
724 return; /* no action, if this is a key release */
725
726 /* kludge... shift forces cursor/number keys */
727 if (vc_kbd_mode(kbd, VC_APPLIC) && !shift_down[KG_SHIFT]) {
728 applkey(vc, app_map[value], 1);
729 return;
730 }
731
732 if (!vc_kbd_led(kbd, VC_NUMLOCK))
733 switch (value) {
734 case KVAL(K_PCOMMA):
735 case KVAL(K_PDOT):
736 k_fn(vc, KVAL(K_REMOVE), 0, regs);
737 return;
738 case KVAL(K_P0):
739 k_fn(vc, KVAL(K_INSERT), 0, regs);
740 return;
741 case KVAL(K_P1):
742 k_fn(vc, KVAL(K_SELECT), 0, regs);
743 return;
744 case KVAL(K_P2):
745 k_cur(vc, KVAL(K_DOWN), 0, regs);
746 return;
747 case KVAL(K_P3):
748 k_fn(vc, KVAL(K_PGDN), 0, regs);
749 return;
750 case KVAL(K_P4):
751 k_cur(vc, KVAL(K_LEFT), 0, regs);
752 return;
753 case KVAL(K_P6):
754 k_cur(vc, KVAL(K_RIGHT), 0, regs);
755 return;
756 case KVAL(K_P7):
757 k_fn(vc, KVAL(K_FIND), 0, regs);
758 return;
759 case KVAL(K_P8):
760 k_cur(vc, KVAL(K_UP), 0, regs);
761 return;
762 case KVAL(K_P9):
763 k_fn(vc, KVAL(K_PGUP), 0, regs);
764 return;
765 case KVAL(K_P5):
766 applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC));
767 return;
768 }
769
770 put_queue(vc, pad_chars[value]);
771 if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
772 put_queue(vc, 10);
773}
774
775static void k_shift(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
776{
777 int old_state = shift_state;
778
779 if (rep)
780 return;
781 /*
782 * Mimic typewriter:
783 * a CapsShift key acts like Shift but undoes CapsLock
784 */
785 if (value == KVAL(K_CAPSSHIFT)) {
786 value = KVAL(K_SHIFT);
787 if (!up_flag)
788 clr_vc_kbd_led(kbd, VC_CAPSLOCK);
789 }
790
791 if (up_flag) {
792 /*
793 * handle the case that two shift or control
794 * keys are depressed simultaneously
795 */
796 if (shift_down[value])
797 shift_down[value]--;
798 } else
799 shift_down[value]++;
800
801 if (shift_down[value])
802 shift_state |= (1 << value);
803 else
804 shift_state &= ~(1 << value);
805
806 /* kludge */
807 if (up_flag && shift_state != old_state && npadch != -1) {
808 if (kbd->kbdmode == VC_UNICODE)
809 to_utf8(vc, npadch & 0xffff);
810 else
811 put_queue(vc, npadch & 0xff);
812 npadch = -1;
813 }
814}
815
816static void k_meta(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
817{
818 if (up_flag)
819 return;
820
821 if (vc_kbd_mode(kbd, VC_META)) {
822 put_queue(vc, '\033');
823 put_queue(vc, value);
824 } else
825 put_queue(vc, value | 0x80);
826}
827
828static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
829{
830 int base;
831
832 if (up_flag)
833 return;
834
835 if (value < 10) {
836 /* decimal input of code, while Alt depressed */
837 base = 10;
838 } else {
839 /* hexadecimal input of code, while AltGr depressed */
840 value -= 10;
841 base = 16;
842 }
843
844 if (npadch == -1)
845 npadch = value;
846 else
847 npadch = npadch * base + value;
848}
849
850static void k_lock(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
851{
852 if (up_flag || rep)
853 return;
854 chg_vc_kbd_lock(kbd, value);
855}
856
857static void k_slock(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
858{
859 k_shift(vc, value, up_flag, regs);
860 if (up_flag || rep)
861 return;
862 chg_vc_kbd_slock(kbd, value);
863 /* try to make Alt, oops, AltGr and such work */
864 if (!key_maps[kbd->lockstate ^ kbd->slockstate]) {
865 kbd->slockstate = 0;
866 chg_vc_kbd_slock(kbd, value);
867 }
868}
869
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500870/* by default, 300ms interval for combination release */
Samuel Thibault77426d72006-04-26 00:14:10 -0400871static unsigned brl_timeout = 300;
872MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for commit on first key release)");
873module_param(brl_timeout, uint, 0644);
874
875static unsigned brl_nbchords = 1;
876MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)");
877module_param(brl_nbchords, uint, 0644);
878
879static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag, struct pt_regs *regs)
880{
881 static unsigned long chords;
882 static unsigned committed;
883
884 if (!brl_nbchords)
885 k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag, regs);
886 else {
887 committed |= pattern;
888 chords++;
889 if (chords == brl_nbchords) {
890 k_unicode(vc, BRL_UC_ROW | committed, up_flag, regs);
891 chords = 0;
892 committed = 0;
893 }
894 }
895}
896
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500897static void k_brl(struct vc_data *vc, unsigned char value, char up_flag, struct pt_regs *regs)
898{
899 static unsigned pressed,committing;
900 static unsigned long releasestart;
901
902 if (kbd->kbdmode != VC_UNICODE) {
903 if (!up_flag)
904 printk("keyboard mode must be unicode for braille patterns\n");
905 return;
906 }
907
908 if (!value) {
909 k_unicode(vc, BRL_UC_ROW, up_flag, regs);
910 return;
911 }
912
913 if (value > 8)
914 return;
915
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500916 if (up_flag) {
917 if (brl_timeout) {
918 if (!committing ||
919 jiffies - releasestart > (brl_timeout * HZ) / 1000) {
920 committing = pressed;
921 releasestart = jiffies;
922 }
923 pressed &= ~(1 << (value - 1));
924 if (!pressed) {
925 if (committing) {
Samuel Thibault77426d72006-04-26 00:14:10 -0400926 k_brlcommit(vc, committing, 0, regs);
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500927 committing = 0;
928 }
929 }
930 } else {
931 if (committing) {
Samuel Thibault77426d72006-04-26 00:14:10 -0400932 k_brlcommit(vc, committing, 0, regs);
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500933 committing = 0;
934 }
935 pressed &= ~(1 << (value - 1));
936 }
937 } else {
938 pressed |= 1 << (value - 1);
939 if (!brl_timeout)
940 committing = pressed;
941 }
942}
943
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944/*
945 * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
946 * or (ii) whatever pattern of lights people want to show using KDSETLED,
947 * or (iii) specified bits of specified words in kernel memory.
948 */
949unsigned char getledstate(void)
950{
951 return ledstate;
952}
953
954void setledstate(struct kbd_struct *kbd, unsigned int led)
955{
956 if (!(led & ~7)) {
957 ledioctl = led;
958 kbd->ledmode = LED_SHOW_IOCTL;
959 } else
960 kbd->ledmode = LED_SHOW_FLAGS;
961 set_leds();
962}
963
964static inline unsigned char getleds(void)
965{
966 struct kbd_struct *kbd = kbd_table + fg_console;
967 unsigned char leds;
968 int i;
969
970 if (kbd->ledmode == LED_SHOW_IOCTL)
971 return ledioctl;
972
973 leds = kbd->ledflagstate;
974
975 if (kbd->ledmode == LED_SHOW_MEM) {
976 for (i = 0; i < 3; i++)
977 if (ledptrs[i].valid) {
978 if (*ledptrs[i].addr & ledptrs[i].mask)
979 leds |= (1 << i);
980 else
981 leds &= ~(1 << i);
982 }
983 }
984 return leds;
985}
986
987/*
988 * This routine is the bottom half of the keyboard interrupt
989 * routine, and runs with all interrupts enabled. It does
990 * console changing, led setting and copy_to_cooked, which can
991 * take a reasonably long time.
992 *
993 * Aside from timing (which isn't really that important for
994 * keyboard interrupts as they happen often), using the software
995 * interrupt routines for this thing allows us to easily mask
996 * this when we don't want any of the above to happen.
997 * This allows for easy and efficient race-condition prevention
Dmitry Torokhov0e739d22006-07-06 00:22:43 -0400998 * for kbd_start => input_inject_event(dev, EV_LED, ...) => ...
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 */
1000
1001static void kbd_bh(unsigned long dummy)
1002{
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001003 struct list_head *node;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004 unsigned char leds = getleds();
1005
1006 if (leds != ledstate) {
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001007 list_for_each(node, &kbd_handler.h_list) {
Dmitry Torokhov0e739d22006-07-06 00:22:43 -04001008 struct input_handle *handle = to_handle_h(node);
1009 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1010 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
1011 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
1012 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 }
1014 }
1015
1016 ledstate = leds;
1017}
1018
1019DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
1020
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
Adrian Bunk0b57ee92005-12-22 21:03:47 -08001022 defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
1023 defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024 (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC))
1025
1026#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
1027 ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
1028
Andreas Mohr0f5e5602006-06-05 00:18:00 -04001029static const unsigned short x86_keycodes[256] =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1031 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1032 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
1033 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
1034 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
1035 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92,
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001036 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349,
1038 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
1039 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361,
1040 291,108,381,281,290,272,292,305,280, 99,112,257,258,359,113,114,
1041 264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116,
1042 377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307,
1043 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
1044 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
1045
1046#ifdef CONFIG_MAC_EMUMOUSEBTN
1047extern int mac_hid_mouse_emulate_buttons(int, int, int);
1048#endif /* CONFIG_MAC_EMUMOUSEBTN */
1049
Adrian Bunk0b57ee92005-12-22 21:03:47 -08001050#ifdef CONFIG_SPARC
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051static int sparc_l1_a_state = 0;
1052extern void sun_do_break(void);
1053#endif
1054
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001055static int emulate_raw(struct vc_data *vc, unsigned int keycode,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 unsigned char up_flag)
1057{
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001058 int code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
1060 switch (keycode) {
1061 case KEY_PAUSE:
1062 put_queue(vc, 0xe1);
1063 put_queue(vc, 0x1d | up_flag);
1064 put_queue(vc, 0x45 | up_flag);
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001065 break;
1066
Jerome Pinotb9ab58d2006-06-26 01:51:23 -04001067 case KEY_HANGEUL:
Dmitry Torokhov0ae051a2006-06-26 01:52:34 -04001068 if (!up_flag)
1069 put_queue(vc, 0xf2);
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001070 break;
1071
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 case KEY_HANJA:
Dmitry Torokhov0ae051a2006-06-26 01:52:34 -04001073 if (!up_flag)
1074 put_queue(vc, 0xf1);
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001075 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001077 case KEY_SYSRQ:
1078 /*
1079 * Real AT keyboards (that's what we're trying
1080 * to emulate here emit 0xe0 0x2a 0xe0 0x37 when
1081 * pressing PrtSc/SysRq alone, but simply 0x54
1082 * when pressing Alt+PrtSc/SysRq.
1083 */
1084 if (sysrq_alt) {
1085 put_queue(vc, 0x54 | up_flag);
1086 } else {
1087 put_queue(vc, 0xe0);
1088 put_queue(vc, 0x2a | up_flag);
1089 put_queue(vc, 0xe0);
1090 put_queue(vc, 0x37 | up_flag);
1091 }
1092 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001094 default:
1095 if (keycode > 255)
1096 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001098 code = x86_keycodes[keycode];
1099 if (!code)
1100 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001101
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001102 if (code & 0x100)
1103 put_queue(vc, 0xe0);
1104 put_queue(vc, (code & 0x7f) | up_flag);
1105
1106 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 }
1108
1109 return 0;
1110}
1111
1112#else
1113
1114#define HW_RAW(dev) 0
1115
1116#warning "Cannot generate rawmode keyboard for your architecture yet."
1117
1118static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
1119{
1120 if (keycode > 127)
1121 return -1;
1122
1123 put_queue(vc, keycode | up_flag);
1124 return 0;
1125}
1126#endif
1127
1128static void kbd_rawcode(unsigned char data)
1129{
1130 struct vc_data *vc = vc_cons[fg_console].d;
1131 kbd = kbd_table + fg_console;
1132 if (kbd->kbdmode == VC_RAW)
1133 put_queue(vc, data);
1134}
1135
Adrian Bunk75c96f82005-05-05 16:16:09 -07001136static void kbd_keycode(unsigned int keycode, int down,
1137 int hw_raw, struct pt_regs *regs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138{
1139 struct vc_data *vc = vc_cons[fg_console].d;
1140 unsigned short keysym, *key_map;
1141 unsigned char type, raw_mode;
1142 struct tty_struct *tty;
1143 int shift_final;
1144
1145 tty = vc->vc_tty;
1146
1147 if (tty && (!tty->driver_data)) {
1148 /* No driver data? Strange. Okay we fix it then. */
1149 tty->driver_data = vc;
1150 }
1151
1152 kbd = kbd_table + fg_console;
1153
1154 if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT)
Fredrik Roubertd2be8ee2006-06-26 00:24:35 -07001155 sysrq_alt = down ? keycode : 0;
Adrian Bunk0b57ee92005-12-22 21:03:47 -08001156#ifdef CONFIG_SPARC
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 if (keycode == KEY_STOP)
1158 sparc_l1_a_state = down;
1159#endif
1160
1161 rep = (down == 2);
1162
1163#ifdef CONFIG_MAC_EMUMOUSEBTN
1164 if (mac_hid_mouse_emulate_buttons(1, keycode, down))
1165 return;
1166#endif /* CONFIG_MAC_EMUMOUSEBTN */
1167
1168 if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw)
1169 if (emulate_raw(vc, keycode, !down << 7))
1170 if (keycode < BTN_MISC)
1171 printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
1172
1173#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
1174 if (keycode == KEY_SYSRQ && (sysrq_down || (down == 1 && sysrq_alt))) {
Fredrik Roubertd2be8ee2006-06-26 00:24:35 -07001175 if (!sysrq_down) {
1176 sysrq_down = down;
1177 sysrq_alt_use = sysrq_alt;
1178 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 return;
1180 }
Fredrik Roubertd2be8ee2006-06-26 00:24:35 -07001181 if (sysrq_down && !down && keycode == sysrq_alt_use)
1182 sysrq_down = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 if (sysrq_down && down && !rep) {
1184 handle_sysrq(kbd_sysrq_xlate[keycode], regs, tty);
1185 return;
1186 }
1187#endif
Adrian Bunk0b57ee92005-12-22 21:03:47 -08001188#ifdef CONFIG_SPARC
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189 if (keycode == KEY_A && sparc_l1_a_state) {
1190 sparc_l1_a_state = 0;
1191 sun_do_break();
1192 }
1193#endif
1194
1195 if (kbd->kbdmode == VC_MEDIUMRAW) {
1196 /*
1197 * This is extended medium raw mode, with keys above 127
1198 * encoded as 0, high 7 bits, low 7 bits, with the 0 bearing
1199 * the 'up' flag if needed. 0 is reserved, so this shouldn't
1200 * interfere with anything else. The two bytes after 0 will
1201 * always have the up flag set not to interfere with older
1202 * applications. This allows for 16384 different keycodes,
1203 * which should be enough.
1204 */
1205 if (keycode < 128) {
1206 put_queue(vc, keycode | (!down << 7));
1207 } else {
1208 put_queue(vc, !down << 7);
1209 put_queue(vc, (keycode >> 7) | 0x80);
1210 put_queue(vc, keycode | 0x80);
1211 }
1212 raw_mode = 1;
1213 }
1214
1215 if (down)
1216 set_bit(keycode, key_down);
1217 else
1218 clear_bit(keycode, key_down);
1219
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001220 if (rep &&
1221 (!vc_kbd_mode(kbd, VC_REPEAT) ||
1222 (tty && !L_ECHO(tty) && tty->driver->chars_in_buffer(tty)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 /*
1224 * Don't repeat a key if the input buffers are not empty and the
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001225 * characters get aren't echoed locally. This makes key repeat
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226 * usable with slow applications and under heavy loads.
1227 */
1228 return;
1229 }
1230
1231 shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
1232 key_map = key_maps[shift_final];
1233
1234 if (!key_map) {
1235 compute_shiftstate();
1236 kbd->slockstate = 0;
1237 return;
1238 }
1239
1240 if (keycode > NR_KEYS)
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -05001241 if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
1242 keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1);
1243 else
1244 return;
1245 else
1246 keysym = key_map[keycode];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 type = KTYP(keysym);
1249
1250 if (type < 0xf0) {
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001251 if (down && !raw_mode)
1252 to_utf8(vc, keysym);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 return;
1254 }
1255
1256 type -= 0xf0;
1257
1258 if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
1259 return;
1260
1261 if (type == KT_LETTER) {
1262 type = KT_LATIN;
1263 if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
1264 key_map = key_maps[shift_final ^ (1 << KG_SHIFT)];
1265 if (key_map)
1266 keysym = key_map[keycode];
1267 }
1268 }
1269
1270 (*k_handler[type])(vc, keysym & 0xff, !down, regs);
1271
1272 if (type != KT_SLOCK)
1273 kbd->slockstate = 0;
1274}
1275
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001276static void kbd_event(struct input_handle *handle, unsigned int event_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277 unsigned int event_code, int value)
1278{
1279 if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
1280 kbd_rawcode(value);
1281 if (event_type == EV_KEY)
1282 kbd_keycode(event_code, value, HW_RAW(handle->dev), handle->dev->regs);
1283 tasklet_schedule(&keyboard_tasklet);
1284 do_poke_blanked_console = 1;
1285 schedule_console_callback();
1286}
1287
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288/*
1289 * When a keyboard (or other input device) is found, the kbd_connect
1290 * function is called. The function then looks at the device, and if it
1291 * likes it, it can open it and get events from it. In this (kbd_connect)
1292 * function, we should decide which VT to bind that keyboard to initially.
1293 */
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001294static struct input_handle *kbd_connect(struct input_handler *handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295 struct input_dev *dev,
Dmitry Torokhov66e66112006-09-14 01:31:59 -04001296 const struct input_device_id *id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297{
1298 struct input_handle *handle;
1299 int i;
1300
1301 for (i = KEY_RESERVED; i < BTN_MISC; i++)
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001302 if (test_bit(i, dev->keybit))
1303 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001305 if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 return NULL;
1307
Dmitry Torokhov22479e12006-08-04 22:51:51 -04001308 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
1309 if (!handle)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001310 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311
1312 handle->dev = dev;
1313 handle->handler = handler;
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001314 handle->name = "kbd";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315
1316 input_open_device(handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317
1318 return handle;
1319}
1320
1321static void kbd_disconnect(struct input_handle *handle)
1322{
1323 input_close_device(handle);
1324 kfree(handle);
1325}
1326
Dmitry Torokhovc7e8dc62006-07-06 00:21:03 -04001327/*
1328 * Start keyboard handler on the new keyboard by refreshing LED state to
1329 * match the rest of the system.
1330 */
1331static void kbd_start(struct input_handle *handle)
1332{
1333 unsigned char leds = ledstate;
1334
1335 tasklet_disable(&keyboard_tasklet);
1336 if (leds != 0xff) {
Dmitry Torokhov0e739d22006-07-06 00:22:43 -04001337 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1338 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
1339 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
1340 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
Dmitry Torokhovc7e8dc62006-07-06 00:21:03 -04001341 }
1342 tasklet_enable(&keyboard_tasklet);
1343}
1344
Dmitry Torokhov66e66112006-09-14 01:31:59 -04001345static const struct input_device_id kbd_ids[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346 {
1347 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1348 .evbit = { BIT(EV_KEY) },
1349 },
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001350
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 {
1352 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1353 .evbit = { BIT(EV_SND) },
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001354 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355
1356 { }, /* Terminating entry */
1357};
1358
1359MODULE_DEVICE_TABLE(input, kbd_ids);
1360
1361static struct input_handler kbd_handler = {
1362 .event = kbd_event,
1363 .connect = kbd_connect,
1364 .disconnect = kbd_disconnect,
Dmitry Torokhovc7e8dc62006-07-06 00:21:03 -04001365 .start = kbd_start,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 .name = "kbd",
1367 .id_table = kbd_ids,
1368};
1369
1370int __init kbd_init(void)
1371{
1372 int i;
Dmitry Torokhov4263cf02006-09-14 01:32:39 -04001373 int error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374
Dmitry Torokhov2b192902006-07-19 01:13:26 -04001375 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1376 kbd_table[i].ledflagstate = KBD_DEFLEDS;
1377 kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
1378 kbd_table[i].ledmode = LED_SHOW_FLAGS;
1379 kbd_table[i].lockstate = KBD_DEFLOCK;
1380 kbd_table[i].slockstate = 0;
1381 kbd_table[i].modeflags = KBD_DEFMODE;
1382 kbd_table[i].kbdmode = VC_XLATE;
1383 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384
Dmitry Torokhov4263cf02006-09-14 01:32:39 -04001385 error = input_register_handler(&kbd_handler);
1386 if (error)
1387 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388
1389 tasklet_enable(&keyboard_tasklet);
1390 tasklet_schedule(&keyboard_tasklet);
1391
1392 return 0;
1393}