diff options
author | Holger Smolinski <Holger.Smolinski@de.ibm.com> | 2008-10-10 15:33:27 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-10-10 15:34:01 -0400 |
commit | 2332ce1a97963b7769e0c2d40492a10a124efba5 (patch) | |
tree | 38728f02d84d91c9ce6e4bb06e871cc19cbe57cd /drivers/s390/char/con3270.c | |
parent | 15e86b0c752d50e910b2cca6e83ce74c4440d06c (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.c | 27 |
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 | */ |
534 | static void | 535 | static void |
535 | con3270_unblank(void) | 536 | con3270_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 | ||
558 | static int con3270_notify(struct notifier_block *self, | ||
559 | unsigned long event, void *data) | ||
560 | { | ||
561 | con3270_flush(); | ||
562 | return NOTIFY_OK; | ||
563 | } | ||
564 | |||
565 | static struct notifier_block on_panic_nb = { | ||
566 | .notifier_call = con3270_notify, | ||
567 | .priority = 0, | ||
568 | }; | ||
569 | |||
570 | static 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 | } |