aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char
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
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')
-rw-r--r--drivers/s390/char/con3215.c27
-rw-r--r--drivers/s390/char/con3270.c27
-rw-r--r--drivers/s390/char/sclp_con.c24
-rw-r--r--drivers/s390/char/sclp_vt220.c26
4 files changed, 86 insertions, 18 deletions
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index d3ec9b55ab35..982cf62ab66d 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -21,6 +21,7 @@
21#include <linux/console.h> 21#include <linux/console.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/reboot.h>
24 25
25#include <linux/slab.h> 26#include <linux/slab.h>
26#include <linux/bootmem.h> 27#include <linux/bootmem.h>
@@ -775,11 +776,11 @@ static struct tty_driver *con3215_device(struct console *c, int *index)
775} 776}
776 777
777/* 778/*
778 * panic() calls console_unblank before the system enters a 779 * panic() calls con3215_flush through a panic_notifier
779 * disabled, endless loop. 780 * before the system enters a disabled, endless loop.
780 */ 781 */
781static void 782static void
782con3215_unblank(void) 783con3215_flush(void)
783{ 784{
784 struct raw3215_info *raw; 785 struct raw3215_info *raw;
785 unsigned long flags; 786 unsigned long flags;
@@ -790,6 +791,23 @@ con3215_unblank(void)
790 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 791 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
791} 792}
792 793
794static int con3215_notify(struct notifier_block *self,
795 unsigned long event, void *data)
796{
797 con3215_flush();
798 return NOTIFY_OK;
799}
800
801static struct notifier_block on_panic_nb = {
802 .notifier_call = con3215_notify,
803 .priority = 0,
804};
805
806static struct notifier_block on_reboot_nb = {
807 .notifier_call = con3215_notify,
808 .priority = 0,
809};
810
793/* 811/*
794 * The console structure for the 3215 console 812 * The console structure for the 3215 console
795 */ 813 */
@@ -797,7 +815,6 @@ static struct console con3215 = {
797 .name = "ttyS", 815 .name = "ttyS",
798 .write = con3215_write, 816 .write = con3215_write,
799 .device = con3215_device, 817 .device = con3215_device,
800 .unblank = con3215_unblank,
801 .flags = CON_PRINTBUFFER, 818 .flags = CON_PRINTBUFFER,
802}; 819};
803 820
@@ -859,6 +876,8 @@ con3215_init(void)
859 raw3215[0] = NULL; 876 raw3215[0] = NULL;
860 return -ENODEV; 877 return -ENODEV;
861 } 878 }
879 atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
880 register_reboot_notifier(&on_reboot_nb);
862 register_console(&con3215); 881 register_console(&con3215);
863 return 0; 882 return 0;
864} 883}
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}
diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c
index 7e619c534bf4..9a25c4bd1421 100644
--- a/drivers/s390/char/sclp_con.c
+++ b/drivers/s390/char/sclp_con.c
@@ -16,6 +16,7 @@
16#include <linux/bootmem.h> 16#include <linux/bootmem.h>
17#include <linux/termios.h> 17#include <linux/termios.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/reboot.h>
19 20
20#include "sclp.h" 21#include "sclp.h"
21#include "sclp_rw.h" 22#include "sclp_rw.h"
@@ -172,7 +173,7 @@ sclp_console_device(struct console *c, int *index)
172 * will be flushed to the SCLP. 173 * will be flushed to the SCLP.
173 */ 174 */
174static void 175static void
175sclp_console_unblank(void) 176sclp_console_flush(void)
176{ 177{
177 unsigned long flags; 178 unsigned long flags;
178 179
@@ -188,6 +189,24 @@ sclp_console_unblank(void)
188 spin_unlock_irqrestore(&sclp_con_lock, flags); 189 spin_unlock_irqrestore(&sclp_con_lock, flags);
189} 190}
190 191
192static int
193sclp_console_notify(struct notifier_block *self,
194 unsigned long event, void *data)
195{
196 sclp_console_flush();
197 return NOTIFY_OK;
198}
199
200static struct notifier_block on_panic_nb = {
201 .notifier_call = sclp_console_notify,
202 .priority = 1,
203};
204
205static struct notifier_block on_reboot_nb = {
206 .notifier_call = sclp_console_notify,
207 .priority = 1,
208};
209
191/* 210/*
192 * used to register the SCLP console to the kernel and to 211 * used to register the SCLP console to the kernel and to
193 * give printk necessary information 212 * give printk necessary information
@@ -197,7 +216,6 @@ static struct console sclp_console =
197 .name = sclp_console_name, 216 .name = sclp_console_name,
198 .write = sclp_console_write, 217 .write = sclp_console_write,
199 .device = sclp_console_device, 218 .device = sclp_console_device,
200 .unblank = sclp_console_unblank,
201 .flags = CON_PRINTBUFFER, 219 .flags = CON_PRINTBUFFER,
202 .index = 0 /* ttyS0 */ 220 .index = 0 /* ttyS0 */
203}; 221};
@@ -241,6 +259,8 @@ sclp_console_init(void)
241 sclp_con_width_htab = 8; 259 sclp_con_width_htab = 8;
242 260
243 /* enable printk-access to this driver */ 261 /* enable printk-access to this driver */
262 atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
263 register_reboot_notifier(&on_reboot_nb);
244 register_console(&sclp_console); 264 register_console(&sclp_console);
245 return 0; 265 return 0;
246} 266}
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index ad51738c4261..9854f19f5e62 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -24,6 +24,8 @@
24#include <linux/bootmem.h> 24#include <linux/bootmem.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/reboot.h>
28
27#include <asm/uaccess.h> 29#include <asm/uaccess.h>
28#include "sclp.h" 30#include "sclp.h"
29 31
@@ -743,24 +745,30 @@ sclp_vt220_con_device(struct console *c, int *index)
743 return sclp_vt220_driver; 745 return sclp_vt220_driver;
744} 746}
745 747
746/* 748static int
747 * This routine is called from panic when the kernel is going to give up. 749sclp_vt220_notify(struct notifier_block *self,
748 * We have to make sure that all buffers will be flushed to the SCLP. 750 unsigned long event, void *data)
749 * Note that this function may be called from within an interrupt context.
750 */
751static void
752sclp_vt220_con_unblank(void)
753{ 751{
754 __sclp_vt220_flush_buffer(); 752 __sclp_vt220_flush_buffer();
753 return NOTIFY_OK;
755} 754}
756 755
756static struct notifier_block on_panic_nb = {
757 .notifier_call = sclp_vt220_notify,
758 .priority = 1,
759};
760
761static struct notifier_block on_reboot_nb = {
762 .notifier_call = sclp_vt220_notify,
763 .priority = 1,
764};
765
757/* Structure needed to register with printk */ 766/* Structure needed to register with printk */
758static struct console sclp_vt220_console = 767static struct console sclp_vt220_console =
759{ 768{
760 .name = SCLP_VT220_CONSOLE_NAME, 769 .name = SCLP_VT220_CONSOLE_NAME,
761 .write = sclp_vt220_con_write, 770 .write = sclp_vt220_con_write,
762 .device = sclp_vt220_con_device, 771 .device = sclp_vt220_con_device,
763 .unblank = sclp_vt220_con_unblank,
764 .flags = CON_PRINTBUFFER, 772 .flags = CON_PRINTBUFFER,
765 .index = SCLP_VT220_CONSOLE_INDEX 773 .index = SCLP_VT220_CONSOLE_INDEX
766}; 774};
@@ -776,6 +784,8 @@ sclp_vt220_con_init(void)
776 if (rc) 784 if (rc)
777 return rc; 785 return rc;
778 /* Attach linux console */ 786 /* Attach linux console */
787 atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
788 register_reboot_notifier(&on_reboot_nb);
779 register_console(&sclp_vt220_console); 789 register_console(&sclp_vt220_console);
780 return 0; 790 return 0;
781} 791}