aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2010-03-22 01:31:26 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2010-04-14 02:26:02 -0400
commit97f5f0cd8cd0a05449cbb77d1e6f02e026875802 (patch)
treee101f38dfd7bf4e759e96617f69ceedd497608e3
parentb91c4be730668e801aa6a2ea95f467cd9a1e0983 (diff)
Input: implement SysRq as a separate input handler
Instead of keeping SysRq support inside of legacy keyboard driver split it out into a separate input handler (filter). This stops most SysRq input events from leaking into evdev clients (some events, such as first SysRq scancode - not keycode - event, are still leaked into both legacy keyboard and evdev). [martinez.javier@gmail.com: fix compile error when CONFIG_MAGIC_SYSRQ is not defined] Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/char/keyboard.c40
-rw-r--r--drivers/char/sysrq.c243
-rw-r--r--include/linux/sysrq.h23
-rw-r--r--kernel/sysctl.c23
4 files changed, 246 insertions, 83 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index ada25bb8941e..50f6c01f44ec 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -38,7 +38,6 @@
38#include <linux/kbd_kern.h> 38#include <linux/kbd_kern.h>
39#include <linux/kbd_diacr.h> 39#include <linux/kbd_diacr.h>
40#include <linux/vt_kern.h> 40#include <linux/vt_kern.h>
41#include <linux/sysrq.h>
42#include <linux/input.h> 41#include <linux/input.h>
43#include <linux/reboot.h> 42#include <linux/reboot.h>
44#include <linux/notifier.h> 43#include <linux/notifier.h>
@@ -82,8 +81,7 @@ void compute_shiftstate(void);
82typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value, 81typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
83 char up_flag); 82 char up_flag);
84static k_handler_fn K_HANDLERS; 83static k_handler_fn K_HANDLERS;
85k_handler_fn *k_handler[16] = { K_HANDLERS }; 84static k_handler_fn *k_handler[16] = { K_HANDLERS };
86EXPORT_SYMBOL_GPL(k_handler);
87 85
88#define FN_HANDLERS\ 86#define FN_HANDLERS\
89 fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\ 87 fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
@@ -147,22 +145,6 @@ static struct ledptr {
147 unsigned char valid:1; 145 unsigned char valid:1;
148} ledptrs[3]; 146} ledptrs[3];
149 147
150/* Simple translation table for the SysRq keys */
151
152#ifdef CONFIG_MAGIC_SYSRQ
153unsigned char kbd_sysrq_xlate[KEY_MAX + 1] =
154 "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
155 "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
156 "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
157 "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
158 "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
159 "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
160 "\r\000/"; /* 0x60 - 0x6f */
161static int sysrq_down;
162static int sysrq_alt_use;
163#endif
164static int sysrq_alt;
165
166/* 148/*
167 * Notifier list for console keyboard events 149 * Notifier list for console keyboard events
168 */ 150 */
@@ -1108,7 +1090,8 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
1108 * pressing PrtSc/SysRq alone, but simply 0x54 1090 * pressing PrtSc/SysRq alone, but simply 0x54
1109 * when pressing Alt+PrtSc/SysRq. 1091 * when pressing Alt+PrtSc/SysRq.
1110 */ 1092 */
1111 if (sysrq_alt) { 1093 if (test_bit(KEY_LEFTALT, key_down) ||
1094 test_bit(KEY_RIGHTALT, key_down)) {
1112 put_queue(vc, 0x54 | up_flag); 1095 put_queue(vc, 0x54 | up_flag);
1113 } else { 1096 } else {
1114 put_queue(vc, 0xe0); 1097 put_queue(vc, 0xe0);
@@ -1176,8 +1159,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
1176 1159
1177 kbd = kbd_table + vc->vc_num; 1160 kbd = kbd_table + vc->vc_num;
1178 1161
1179 if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT)
1180 sysrq_alt = down ? keycode : 0;
1181#ifdef CONFIG_SPARC 1162#ifdef CONFIG_SPARC
1182 if (keycode == KEY_STOP) 1163 if (keycode == KEY_STOP)
1183 sparc_l1_a_state = down; 1164 sparc_l1_a_state = down;
@@ -1190,21 +1171,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
1190 if (keycode < BTN_MISC && printk_ratelimit()) 1171 if (keycode < BTN_MISC && printk_ratelimit())
1191 printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode); 1172 printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
1192 1173
1193#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
1194 if (keycode == KEY_SYSRQ && (sysrq_down || (down == 1 && sysrq_alt))) {
1195 if (!sysrq_down) {
1196 sysrq_down = down;
1197 sysrq_alt_use = sysrq_alt;
1198 }
1199 return;
1200 }
1201 if (sysrq_down && !down && keycode == sysrq_alt_use)
1202 sysrq_down = 0;
1203 if (sysrq_down && down && !rep) {
1204 handle_sysrq(kbd_sysrq_xlate[keycode], tty);
1205 return;
1206 }
1207#endif
1208#ifdef CONFIG_SPARC 1174#ifdef CONFIG_SPARC
1209 if (keycode == KEY_A && sparc_l1_a_state) { 1175 if (keycode == KEY_A && sparc_l1_a_state) {
1210 sparc_l1_a_state = 0; 1176 sparc_l1_a_state = 0;
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 59de2525d303..193f9c214946 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -1,7 +1,4 @@
1/* -*- linux-c -*- 1/*
2 *
3 * $Id: sysrq.c,v 1.15 1998/08/23 14:56:41 mj Exp $
4 *
5 * Linux Magic System Request Key Hacks 2 * Linux Magic System Request Key Hacks
6 * 3 *
7 * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> 4 * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
@@ -10,8 +7,13 @@
10 * (c) 2000 Crutcher Dunnavant <crutcher+kernel@datastacks.com> 7 * (c) 2000 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
11 * overhauled to use key registration 8 * overhauled to use key registration
12 * based upon discusions in irc://irc.openprojects.net/#kernelnewbies 9 * based upon discusions in irc://irc.openprojects.net/#kernelnewbies
10 *
11 * Copyright (c) 2010 Dmitry Torokhov
12 * Input handler conversion
13 */ 13 */
14 14
15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16
15#include <linux/sched.h> 17#include <linux/sched.h>
16#include <linux/interrupt.h> 18#include <linux/interrupt.h>
17#include <linux/mm.h> 19#include <linux/mm.h>
@@ -39,33 +41,34 @@
39#include <linux/hrtimer.h> 41#include <linux/hrtimer.h>
40#include <linux/oom.h> 42#include <linux/oom.h>
41#include <linux/slab.h> 43#include <linux/slab.h>
44#include <linux/input.h>
42 45
43#include <asm/ptrace.h> 46#include <asm/ptrace.h>
44#include <asm/irq_regs.h> 47#include <asm/irq_regs.h>
45 48
46/* Whether we react on sysrq keys or just ignore them */ 49/* Whether we react on sysrq keys or just ignore them */
47int __read_mostly __sysrq_enabled = 1; 50static int __read_mostly sysrq_enabled = 1;
48 51static bool __read_mostly sysrq_always_enabled;
49static int __read_mostly sysrq_always_enabled;
50 52
51int sysrq_on(void) 53static bool sysrq_on(void)
52{ 54{
53 return __sysrq_enabled || sysrq_always_enabled; 55 return sysrq_enabled || sysrq_always_enabled;
54} 56}
55 57
56/* 58/*
57 * A value of 1 means 'all', other nonzero values are an op mask: 59 * A value of 1 means 'all', other nonzero values are an op mask:
58 */ 60 */
59static inline int sysrq_on_mask(int mask) 61static bool sysrq_on_mask(int mask)
60{ 62{
61 return sysrq_always_enabled || __sysrq_enabled == 1 || 63 return sysrq_always_enabled ||
62 (__sysrq_enabled & mask); 64 sysrq_enabled == 1 ||
65 (sysrq_enabled & mask);
63} 66}
64 67
65static int __init sysrq_always_enabled_setup(char *str) 68static int __init sysrq_always_enabled_setup(char *str)
66{ 69{
67 sysrq_always_enabled = 1; 70 sysrq_always_enabled = true;
68 printk(KERN_INFO "debug: sysrq always enabled.\n"); 71 pr_info("sysrq always enabled.\n");
69 72
70 return 1; 73 return 1;
71} 74}
@@ -76,6 +79,7 @@ __setup("sysrq_always_enabled", sysrq_always_enabled_setup);
76static void sysrq_handle_loglevel(int key, struct tty_struct *tty) 79static void sysrq_handle_loglevel(int key, struct tty_struct *tty)
77{ 80{
78 int i; 81 int i;
82
79 i = key - '0'; 83 i = key - '0';
80 console_loglevel = 7; 84 console_loglevel = 7;
81 printk("Loglevel set to %d\n", i); 85 printk("Loglevel set to %d\n", i);
@@ -101,7 +105,7 @@ static struct sysrq_key_op sysrq_SAK_op = {
101 .enable_mask = SYSRQ_ENABLE_KEYBOARD, 105 .enable_mask = SYSRQ_ENABLE_KEYBOARD,
102<