diff options
author | Holger Smolinski <Holger.Smolinski@de.ibm.com> | 2008-10-10 21:33:27 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-10-10 21:34:01 +0200 |
commit | 2332ce1a97963b7769e0c2d40492a10a124efba5 (patch) | |
tree | 38728f02d84d91c9ce6e4bb06e871cc19cbe57cd /drivers/s390/char/con3270.c | |
parent | 15e86b0c752d50e910b2cca6e83ce74c4440d06c (diff) | |
download | op-kernel-dev-2332ce1a97963b7769e0c2d40492a10a124efba5.zip op-kernel-dev-2332ce1a97963b7769e0c2d40492a10a124efba5.tar.gz |
[S390] console flush on panic / reboot
The s390 console drivers use the unblank callback of the console
structure to flush the console buffer. In case of a panic or a
reboot the CPU doing the callback can block on the console i/o.
The other CPUs in the system continue to work. For panic this is
not a good idea.
Replace the unblank callback with proper panic/reboot notifier.
These get called after all but one CPU have been stopped.
Signed-off-by: Holger Smolinski <Holger.Smolinski@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char/con3270.c')
-rw-r--r-- | drivers/s390/char/con3270.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 3c07974..d028d2e 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -15,6 +15,7 @@ #include <linux/list.h> #include <linux/types.h> #include <linux/err.h> +#include <linux/reboot.h> #include <asm/ccwdev.h> #include <asm/cio.h> @@ -528,11 +529,11 @@ con3270_wait_write(struct con3270 *cp) } /* - * panic() calls console_unblank before the system enters a - * disabled, endless loop. + * panic() calls con3270_flush through a panic_notifier + * before the system enters a disabled, endless loop. */ static void -con3270_unblank(void) +con3270_flush(void) { struct con3270 *cp; unsigned long flags; @@ -554,6 +555,23 @@ con3270_unblank(void) spin_unlock_irqrestore(&cp->view.lock, flags); } +static int con3270_notify(struct notifier_block *self, + unsigned long event, void *data) +{ + con3270_flush(); + return NOTIFY_OK; +} + +static struct notifier_block on_panic_nb = { + .notifier_call = con3270_notify, + .priority = 0, +}; + +static struct notifier_block on_reboot_nb = { + .notifier_call = con3270_notify, + .priority = 0, +}; + /* * The console structure for the 3270 console */ @@ -561,7 +579,6 @@ static struct console con3270 = { .name = "tty3270", .write = con3270_write, .device = con3270_device, - .unblank = con3270_unblank, .flags = CON_PRINTBUFFER, }; @@ -623,6 +640,8 @@ con3270_init(void) condev->cline->len = 0; con3270_create_status(condev); condev->input = alloc_string(&condev->freemem, 80); + atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb); + register_reboot_notifier(&on_reboot_nb); register_console(&con3270); return 0; } |