aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char/con3270.c
diff options
context:
space:
mode:
authorHolger Smolinski <Holger.Smolinski@de.ibm.com>2008-10-10 15:33:27 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-10-10 15:34:01 -0400
commit2332ce1a97963b7769e0c2d40492a10a124efba5 (patch)
tree38728f02d84d91c9ce6e4bb06e871cc19cbe57cd /drivers/s390/char/con3270.c
parent15e86b0c752d50e910b2cca6e83ce74c4440d06c (diff)
[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.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index 3c07974886ed..d028d2ee83dd 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -15,6 +15,7 @@
15#include <linux/list.h> 15#include <linux/list.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/err.h> 17#include <linux/err.h>
18#include <linux/reboot.h>
18 19
19#include <asm/ccwdev.h> 20#include <asm/ccwdev.h>
20#include <asm/cio.h> 21#include <asm/cio.h>
@@ -528,11 +529,11 @@ con3270_wait_write(struct con3270 *cp)
528} 529}
529 530
530/* 531/*
531 * panic() calls console_unblank before the system enters a 532 * panic() calls con3270_flush through a panic_notifier
532 * disabled, endless loop. 533 * before the system enters a disabled, endless loop.
533 */ 534 */
534static void 535static void
535con3270_unblank(void) 536con3270_flush(void)
536{ 537{
537 struct con3270 *cp; 538 struct con3270 *cp;
538 unsigned long flags; 539 unsigned long flags;
@@ -554,6 +555,23 @@ con3270_unblank(void)
554 spin_unlock_irqrestore(&cp->view.lock, flags); 555 spin_unlock_irqrestore(&cp->view.lock, flags);
555} 556}
556 557
558static int con3270_notify(struct notifier_block *self,
559 unsigned long event, void *data)
560{
561 con3270_flush();
562 return NOTIFY_OK;
563}
564
565static struct notifier_block on_panic_nb = {
566 .notifier_call = con3270_notify,
567 .priority = 0,
568};
569
570static struct notifier_block on_reboot_nb = {
571 .notifier_call = con3270_notify,
572 .priority = 0,
573};
574
557/* 575/*
558 * The console structure for the 3270 console 576 * The console structure for the 3270 console
559 */ 577 */
@@ -561,7 +579,6 @@ static struct console con3270 = {
561 .name = "tty3270", 579 .name = "tty3270",
562 .write = con3270_write, 580 .write = con3270_write,
563 .device = con3270_device, 581 .device = con3270_device,
564 .unblank = con3270_unblank,
565 .flags = CON_PRINTBUFFER, 582 .flags = CON_PRINTBUFFER,
566}; 583};
567 584
@@ -623,6 +640,8 @@ con3270_init(void)
623 condev->cline->len = 0; 640 condev->cline->len = 0;
624 con3270_create_status(condev); 641 con3270_create_status(condev);
625 condev->input = alloc_string(&condev->freemem, 80); 642 condev->input = alloc_string(&condev->freemem, 80);
643 atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
644 register_reboot_notifier(&on_reboot_nb);
626 register_console(&con3270); 645 register_console(&con3270);
627 return 0; 646 return 0;
628} 647}