Commit 99d4a6c9 authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] Add panic blinking to 2.6

This patch readds the panic blinking that was in 2.4 to 2.6.  This is
useful to see when you're in X that the machine has paniced 

It addresses previously criticism.
It should work now when the keyboard interrupt is off.
It doesn't fully emulate the handler, but has a timeout
for this case.
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 99770da7
......@@ -813,6 +813,41 @@ void i8042_controller_cleanup(void)
}
static int blink_frequency = 500;
module_param_named(panicblink, blink_frequency, int, 0600);
/* Catch the case when the kbd interrupt is off */
#define DELAY do { mdelay(1); if (++delay > 10) return delay; } while(0)
/* Tell the user who may be running in X and not see the console that we have
panic'ed. This is to distingush panics from "real" lockups. */
static long i8042_panic_blink(long count)
{
long delay = 0;
static long last_blink;
static char led;
/* Roughly 1/2s frequency. KDB uses about 1s. Make sure it is
different. */
if (!blink_frequency)
return 0;
if (count - last_blink < blink_frequency)
return 0;
led ^= 0x01 | 0x04;
while (i8042_read_status() & I8042_STR_IBF)
DELAY;
i8042_write_data(0xed); /* set leds */
DELAY;
while (i8042_read_status() & I8042_STR_IBF)
DELAY;
DELAY;
i8042_write_data(led);
DELAY;
last_blink = count;
return delay;
}
#undef DELAY
/*
* Here we try to restore the original BIOS settings
*/
......@@ -863,6 +898,8 @@ static int i8042_controller_resume(void)
*/
mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
panic_blink = i8042_panic_blink;
return 0;
}
......@@ -1077,6 +1114,8 @@ void __exit i8042_exit(void)
driver_unregister(&i8042_driver);
i8042_platform_exit();
panic_blink = NULL;
}
module_init(i8042_init);
......
......@@ -66,6 +66,7 @@ void __might_sleep(char *file, int line);
})
extern struct notifier_block *panic_notifier_list;
extern long (*panic_blink)(long time);
NORET_TYPE void panic(const char * fmt, ...)
__attribute__ ((NORET_AND format (printf, 1, 2)));
asmlinkage NORET_TYPE void do_exit(long error_code)
......
......@@ -36,6 +36,15 @@ static int __init panic_setup(char *str)
}
__setup("panic=", panic_setup);
static long no_blink(long time)
{
return 0;
}
/* Returns how long it waited in ms */
long (*panic_blink)(long time) = no_blink;
EXPORT_SYMBOL(panic_blink);
/**
* panic - halt the system
* @fmt: The text string to print
......@@ -48,6 +57,7 @@ __setup("panic=", panic_setup);
NORET_TYPE void panic(const char * fmt, ...)
{
long i;
static char buf[1024];
va_list args;
#if defined(CONFIG_ARCH_S390)
......@@ -69,15 +79,16 @@ NORET_TYPE void panic(const char * fmt, ...)
if (panic_timeout > 0)
{
int i;
/*
* Delay timeout seconds before rebooting the machine.
* We can't use the "normal" timers since we just panicked..
*/
printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
for (i = 0; i < panic_timeout; i++) {
for (i = 0; i < panic_timeout*1000; ) {
touch_nmi_watchdog();
mdelay(1000);
i += panic_blink(i);
mdelay(1);
i++;
}
/*
* Should we run the reboot notifier. For the moment Im
......@@ -98,8 +109,11 @@ NORET_TYPE void panic(const char * fmt, ...)
disabled_wait(caller);
#endif
local_irq_enable();
for (;;)
;
for (i = 0;;) {
i += panic_blink(i);
mdelay(1);
i++;
}
}
EXPORT_SYMBOL(panic);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment