diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-03-24 12:46:36 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2010-03-24 12:46:36 +1100 |
commit | 537ff1000d00ce39f117e0b660835d2647e93a6c (patch) | |
tree | 465574d485360bda16b6bb3ae68a11918e5af740 /drivers/char/sysrq.c | |
parent | 013325c89a5347554e3def26faeb597e7e62841d (diff) |
Revert "Input: implement SysRq as a separate input handler"
This reverts commit edc6e384f9d96e54a6d03068d3b03fa5b56b6449.
Diffstat (limited to 'drivers/char/sysrq.c')
-rw-r--r-- | drivers/char/sysrq.c | 222 |
1 files changed, 29 insertions, 193 deletions
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 1883dd8ee8f1..1ae2de7d8b4f 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -1,4 +1,7 @@ -/* +/* -*- linux-c -*- + * + * $Id: sysrq.c,v 1.15 1998/08/23 14:56:41 mj Exp $ + * * Linux Magic System Request Key Hacks * * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> @@ -7,13 +10,8 @@ * (c) 2000 Crutcher Dunnavant <crutcher+kernel@datastacks.com> * overhauled to use key registration * based upon discusions in irc://irc.openprojects.net/#kernelnewbies - * - * Copyright (c) 2010 Dmitry Torokhov - * Input handler conversion */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include <linux/sched.h> #include <linux/interrupt.h> #include <linux/mm.h> @@ -40,34 +38,33 @@ #include <linux/workqueue.h> #include <linux/hrtimer.h> #include <linux/oom.h> -#include <linux/input.h> #include <asm/ptrace.h> #include <asm/irq_regs.h> /* Whether we react on sysrq keys or just ignore them */ -static int __read_mostly sysrq_enabled = 1; -static bool __read_mostly sysrq_always_enabled; +int __read_mostly __sysrq_enabled = 1; -static bool sysrq_on(void) +static int __read_mostly sysrq_always_enabled; + +int sysrq_on(void) { - return sysrq_enabled || sysrq_always_enabled; + return __sysrq_enabled || sysrq_always_enabled; } /* * A value of 1 means 'all', other nonzero values are an op mask: */ -static bool sysrq_on_mask(int mask) +static inline int sysrq_on_mask(int mask) { - return sysrq_always_enabled || - sysrq_enabled == 1 || - (sysrq_enabled & mask); + return sysrq_always_enabled || __sysrq_enabled == 1 || + (__sysrq_enabled & mask); } static int __init sysrq_always_enabled_setup(char *str) { - sysrq_always_enabled = true; - pr_info("sysrq always enabled.\n"); + sysrq_always_enabled = 1; + printk(KERN_INFO "debug: sysrq always enabled.\n"); return 1; } @@ -78,7 +75,6 @@ __setup("sysrq_always_enabled", sysrq_always_enabled_setup); static void sysrq_handle_loglevel(int key, struct tty_struct *tty) { int i; - i = key - '0'; console_loglevel = 7; printk("Loglevel set to %d\n", i); @@ -104,7 +100,7 @@ static struct sysrq_key_op sysrq_SAK_op = { .enable_mask = SYSRQ_ENABLE_KEYBOARD, }; #else -#define sysrq_SAK_op (*(struct sysrq_key_op *)NULL) +#define sysrq_SAK_op (*(struct sysrq_key_op *)0) #endif #ifdef CONFIG_VT @@ -122,7 +118,7 @@ static struct sysrq_key_op sysrq_unraw_op = { .enable_mask = SYSRQ_ENABLE_KEYBOARD, }; #else -#define sysrq_unraw_op (*(struct sysrq_key_op *)NULL) +#define sysrq_unraw_op (*(struct sysrq_key_op *)0) #endif /* CONFIG_VT */ static void sysrq_handle_crash(int key, struct tty_struct *tty) @@ -198,7 +194,7 @@ static struct sysrq_key_op sysrq_showlocks_op = { .action_msg = "Show Locks Held", }; #else -#define sysrq_showlocks_op (*(struct sysrq_key_op *)NULL) +#define sysrq_showlocks_op (*(struct sysrq_key_op *)0) #endif #ifdef CONFIG_SMP @@ -301,7 +297,7 @@ static struct sysrq_key_op sysrq_ftrace_dump_op = { .enable_mask = SYSRQ_ENABLE_DUMP, }; #else -#define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)NULL) +#define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)0) #endif static void sysrq_handle_showmem(int key, struct tty_struct *tty) @@ -480,7 +476,6 @@ struct sysrq_key_op *__sysrq_get_key_op(int key) i = sysrq_key_table_key2index(key); if (i != -1) op_p = sysrq_key_table[i]; - return op_p; } @@ -492,7 +487,11 @@ static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p) sysrq_key_table[i] = op_p; } -static void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) +/* + * This is the non-locking version of handle_sysrq. It must/can only be called + * by sysrq key handlers, as they are inside of the lock + */ +void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) { struct sysrq_key_op *op_p; int orig_log_level; @@ -544,6 +543,10 @@ static void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) spin_unlock_irqrestore(&sysrq_key_table_lock, flags); } +/* + * This function is called by the keyboard handler when SysRq is pressed + * and any other keycode arrives. + */ void handle_sysrq(int key, struct tty_struct *tty) { if (sysrq_on()) @@ -551,148 +554,6 @@ void handle_sysrq(int key, struct tty_struct *tty) } EXPORT_SYMBOL(handle_sysrq); -/* Simple translation table for the SysRq keys */ -static const unsigned char sysrq_xlate[KEY_MAX + 1] = - "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ - "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ - "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ - "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */ - "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */ - "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ - "\r\000/"; /* 0x60 - 0x6f */ - -static bool sysrq_down; -static int sysrq_alt_use; -static int sysrq_alt; - -static bool sysrq_filter(struct input_handle *handle, unsigned int type, - unsigned int code, int value) -{ - - if (type != EV_KEY) - goto out; - - switch (code) { - - case KEY_LEFTALT: - case KEY_RIGHTALT: - if (value) - sysrq_alt = code; - else if (sysrq_down && code == sysrq_alt_use) - sysrq_down = false; - break; - - case KEY_SYSRQ: - if (value == 1 && sysrq_alt) { - sysrq_down = true; - sysrq_alt_use = sysrq_alt; - } - - break; - - default: - if (sysrq_down && value && value != 2) { - struct vc_data *vc = vc_cons[fg_console].d; - - __handle_sysrq(sysrq_xlate[code], vc->vc_tty, 1); - } - } - -out: - return sysrq_down; -} - -static int sysrq_connect(struct input_handler *handler, - struct input_dev *dev, - const struct input_device_id *id) -{ - struct input_handle *handle; - int error; - - sysrq_down = false; - sysrq_alt = 0; - - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = "sysrq"; - - error = input_register_handle(handle); - if (error) { - pr_err("Failed to register input sysrq handler, error %d\n", - error); - goto err_free; - } - - error = input_open_device(handle); - if (error) { - pr_err("Failed to open input device, error %d\n", error); - goto err_unregister; - } - - return 0; - - err_unregister: - input_unregister_handle(handle); - err_free: - kfree(handle); - return error; -} - -static void sysrq_disconnect(struct input_handle *handle) -{ - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -/* - * We are matching on KEY_LEFTALT insteard of KEY_SYSRQ because not all - * keyboards have SysRq ikey predefined and so user may add it to keymap - * later, but we expect all such keyboards to have left alt. - */ -static const struct input_device_id sysrq_ids[] = { - { - .flags = INPUT_DEVICE_ID_MATCH_EVBIT | - INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { BIT_MASK(KEY_LEFTALT) }, - }, - { }, -}; - -static struct input_handler sysrq_handler = { - .filter = sysrq_filter, - .connect = sysrq_connect, - .disconnect = sysrq_disconnect, - .name = "sysrq", - .id_table = sysrq_ids, -}; - -int sysrq_toggle_support(int enable_mask) -{ - bool was_enabled = sysrq_on(); - int error; - - sysrq_enabled = enable_mask; - - if (was_enabled != sysrq_on()) { - if (sysrq_on()) { - error = input_register_handler(&sysrq_handler); - if (error) - pr_err("Failed to register input handler, error %d", - error); - - } else - input_unregister_handler(&sysrq_handler); - } - - return 0; -} - static int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p, struct sysrq_key_op *remove_op_p) { @@ -737,7 +598,6 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, return -EFAULT; __handle_sysrq(c, NULL, 0); } - return count; } @@ -745,34 +605,10 @@ static const struct file_operations proc_sysrq_trigger_operations = { .write = write_sysrq_trigger, }; -static void sysrq_init_procfs(void) -{ - if (!proc_create("sysrq-trigger", S_IWUSR, NULL, - &proc_sysrq_trigger_operations)) - pr_err("Failed to register proc interface\n"); -} - -#else - -static inline void sysrq_init_procfs(void) -{ -} - -#endif - static int __init sysrq_init(void) { - int error; - - sysrq_init_procfs(); - - if (sysrq_on()) { - error = input_register_handler(&sysrq_handler); - if (error) - pr_err("Failed to register input handler, error %d", - error); - } - + proc_create("sysrq-trigger", S_IWUSR, NULL, &proc_sysrq_trigger_operations); return 0; } module_init(sysrq_init); +#endif |