summaryrefslogtreecommitdiff
path: root/drivers/s390/char
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2008-02-09 18:24:33 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-02-09 18:24:39 +0100
commit59eb1ca7a8906412478656ba79261036261f4b76 (patch)
treee21974f7a9f07cc1f4f2378428ea1c76b9259018 /drivers/s390/char
parentbf3f837804997e5f5d9888051e9e5356961af0f2 (diff)
[S390] sclp_vt220: Fix vt220 initialization
There are two problems in the vt220 intialization: o Currently the vt220 console looses early printk events until the the vt220 tty is registered. o console should work if tty_register fails sclp_vt220_con_init calls __sclp_vt220_init and register_console. It does not register the driver with the sclp core code via sclp_register. That results in an sclp_send_mask=0. Therefore, __sclp_vt220_emit will reject buffers with EIO. Unfortunately register_console will cause the printk buffer to be sent to the console and, therefore, every early message gets dropped. The sclp_send_mask is set later during boot, when sclp_vt220_tty_init calls sclp_register. The solution is to move the sclp_register call from sclp_vt220_tty_init to __sclp_vt220_init. This makes sure that the console is properly registered with the sclp subsystem before the first log buffer messages are passed to the vt220 console. We also adopt the cleanup on error to keep the console alive if tty_register fails. Thanks to Peter Oberparleiter and Heiko Carstens for review and ideas for improvement. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char')
-rw-r--r--drivers/s390/char/sclp_vt220.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 68071622d4b..f47f4a768be 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -3,7 +3,7 @@
* SCLP VT220 terminal driver.
*
* S390 version
- * Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Copyright IBM Corp. 2003,2008
* Author(s): Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com>
*/
@@ -632,6 +632,9 @@ static void __init __sclp_vt220_cleanup(void)
else
free_bootmem((unsigned long) page, PAGE_SIZE);
}
+ if (!list_empty(&sclp_vt220_register.list))
+ sclp_unregister(&sclp_vt220_register);
+ sclp_vt220_initialized = 0;
}
static int __init __sclp_vt220_init(void)
@@ -639,6 +642,7 @@ static int __init __sclp_vt220_init(void)
void *page;
int i;
int num_pages;
+ int rc;
if (sclp_vt220_initialized)
return 0;
@@ -667,7 +671,14 @@ static int __init __sclp_vt220_init(void)
}
list_add_tail((struct list_head *) page, &sclp_vt220_empty);
}
- return 0;
+ rc = sclp_register(&sclp_vt220_register);
+ if (rc) {
+ printk(KERN_ERR SCLP_VT220_PRINT_HEADER
+ "could not register vt220 - "
+ "sclp_register returned %d\n", rc);
+ __sclp_vt220_cleanup();
+ }
+ return rc;
}
static const struct tty_operations sclp_vt220_ops = {
@@ -688,22 +699,17 @@ static int __init sclp_vt220_tty_init(void)
{
struct tty_driver *driver;
int rc;
+ int cleanup;
/* Note: we're not testing for CONSOLE_IS_SCLP here to preserve
* symmetry between VM and LPAR systems regarding ttyS1. */
driver = alloc_tty_driver(1);
if (!driver)
return -ENOMEM;
+ cleanup = !sclp_vt220_initialized;
rc = __sclp_vt220_init();
if (rc)
goto out_driver;
- rc = sclp_register(&sclp_vt220_register);
- if (rc) {
- printk(KERN_ERR SCLP_VT220_PRINT_HEADER
- "could not register tty - "
- "sclp_register returned %d\n", rc);
- goto out_init;
- }
driver->owner = THIS_MODULE;
driver->driver_name = SCLP_VT220_DRIVER_NAME;
@@ -721,15 +727,14 @@ static int __init sclp_vt220_tty_init(void)
printk(KERN_ERR SCLP_VT220_PRINT_HEADER
"could not register tty - "
"tty_register_driver returned %d\n", rc);
- goto out_sclp;
+ goto out_init;
}
sclp_vt220_driver = driver;
return 0;
-out_sclp:
- sclp_unregister(&sclp_vt220_register);
out_init:
- __sclp_vt220_cleanup();
+ if (cleanup)
+ __sclp_vt220_cleanup();
out_driver:
put_tty_driver(driver);
return rc;