X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fsysrq.c;h=057eaf87b9b28eb3ce2a13f5491a859cefc48cfb;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=da52bff37f97dc08c1a2ae79f1a4e9d9dba4aec8;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index da52bff37..057eaf87b 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -98,6 +98,7 @@ static struct sysrq_key_op sysrq_unraw_op = { static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs, struct tty_struct *tty) { + local_irq_enable(); machine_restart(NULL); } @@ -216,9 +217,19 @@ static struct sysrq_key_op sysrq_kill_op = { /* END SIGNAL SYSRQ HANDLERS BLOCK */ +static void sysrq_handle_unrt(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + normalize_rt_tasks(); +} +static struct sysrq_key_op sysrq_unrt_op = { + .handler = sysrq_handle_unrt, + .help_msg = "Nice", + .action_msg = "Nice All RT Tasks" +}; /* Key Operations table and lock */ -static spinlock_t sysrq_key_table_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(sysrq_key_table_lock); #define SYSRQ_KEY_TABLE_LENGTH 36 static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = { /* 0 */ &sysrq_loglevel_op, @@ -250,7 +261,7 @@ static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = { #endif /* l */ NULL, /* m */ &sysrq_showmem_op, -/* n */ NULL, +/* n */ &sysrq_unrt_op, /* o */ NULL, /* This will often be registered as 'Off' at init time */ /* p */ &sysrq_showregs_op, @@ -283,14 +294,6 @@ static int sysrq_key_table_key2index(int key) { return retval; } -/* - * table lock and unlocking functions, exposed to modules - */ - -void __sysrq_lock_table (void) { spin_lock(&sysrq_key_table_lock); } - -void __sysrq_unlock_table (void) { spin_unlock(&sysrq_key_table_lock); } - /* * get and put functions for the table, exposed to modules. */ @@ -323,8 +326,9 @@ void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty) struct sysrq_key_op *op_p; int orig_log_level; int i, j; + unsigned long flags; - __sysrq_lock_table(); + spin_lock_irqsave(&sysrq_key_table_lock, flags); orig_log_level = console_loglevel; console_loglevel = 7; printk(KERN_INFO "SysRq : "); @@ -346,7 +350,7 @@ void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty) printk ("\n"); console_loglevel = orig_log_level; } - __sysrq_unlock_table(); + spin_unlock_irqrestore(&sysrq_key_table_lock, flags); } /* @@ -361,8 +365,34 @@ void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty) __handle_sysrq(key, pt_regs, tty); } +int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p, + struct sysrq_key_op *remove_op_p) { + + int retval; + unsigned long flags; + + spin_lock_irqsave(&sysrq_key_table_lock, flags); + if (__sysrq_get_key_op(key) == remove_op_p) { + __sysrq_put_key_op(key, insert_op_p); + retval = 0; + } else { + retval = -1; + } + spin_unlock_irqrestore(&sysrq_key_table_lock, flags); + + return retval; +} + +int register_sysrq_key(int key, struct sysrq_key_op *op_p) +{ + return __sysrq_swap_key_ops(key, op_p, NULL); +} + +int unregister_sysrq_key(int key, struct sysrq_key_op *op_p) +{ + return __sysrq_swap_key_ops(key, NULL, op_p); +} + EXPORT_SYMBOL(handle_sysrq); -EXPORT_SYMBOL(__sysrq_lock_table); -EXPORT_SYMBOL(__sysrq_unlock_table); -EXPORT_SYMBOL(__sysrq_get_key_op); -EXPORT_SYMBOL(__sysrq_put_key_op); +EXPORT_SYMBOL(register_sysrq_key); +EXPORT_SYMBOL(unregister_sysrq_key);