mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 00:20:32 +00:00
[S390] sclp: simplify vt220 cleanup logic
Fix a number of sclp_vt220 cleanup problems: * fix list_empty check after list_del() * mark init-only flag as __initdata * remove implicit dependency between slab_available() and num_pages * straighten multiple init handling (use init count) Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
This commit is contained in:
parent
773922e1da
commit
ad211790c0
1 changed files with 28 additions and 27 deletions
|
@ -82,8 +82,8 @@ static struct sclp_vt220_request *sclp_vt220_current_request;
|
||||||
/* Number of characters in current request buffer */
|
/* Number of characters in current request buffer */
|
||||||
static int sclp_vt220_buffered_chars;
|
static int sclp_vt220_buffered_chars;
|
||||||
|
|
||||||
/* Flag indicating whether this driver has already been initialized */
|
/* Counter controlling core driver initialization. */
|
||||||
static int sclp_vt220_initialized = 0;
|
static int __initdata sclp_vt220_init_count;
|
||||||
|
|
||||||
/* Flag indicating that sclp_vt220_current_request should really
|
/* Flag indicating that sclp_vt220_current_request should really
|
||||||
* have been already queued but wasn't because the SCLP was processing
|
* have been already queued but wasn't because the SCLP was processing
|
||||||
|
@ -609,10 +609,8 @@ sclp_vt220_flush_buffer(struct tty_struct *tty)
|
||||||
sclp_vt220_emit_current();
|
sclp_vt220_emit_current();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Release allocated pages. */
|
||||||
* Initialize all relevant components and register driver with system.
|
static void __init __sclp_vt220_free_pages(void)
|
||||||
*/
|
|
||||||
static void __init __sclp_vt220_cleanup(void)
|
|
||||||
{
|
{
|
||||||
struct list_head *page, *p;
|
struct list_head *page, *p;
|
||||||
|
|
||||||
|
@ -623,21 +621,30 @@ static void __init __sclp_vt220_cleanup(void)
|
||||||
else
|
else
|
||||||
free_bootmem((unsigned long) page, PAGE_SIZE);
|
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)
|
/* Release memory and unregister from sclp core. Controlled by init counting -
|
||||||
|
* only the last invoker will actually perform these actions. */
|
||||||
|
static void __init __sclp_vt220_cleanup(void)
|
||||||
|
{
|
||||||
|
sclp_vt220_init_count--;
|
||||||
|
if (sclp_vt220_init_count != 0)
|
||||||
|
return;
|
||||||
|
sclp_unregister(&sclp_vt220_register);
|
||||||
|
__sclp_vt220_free_pages();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate buffer pages and register with sclp core. Controlled by init
|
||||||
|
* counting - only the first invoker will actually perform these actions. */
|
||||||
|
static int __init __sclp_vt220_init(int num_pages)
|
||||||
{
|
{
|
||||||
void *page;
|
void *page;
|
||||||
int i;
|
int i;
|
||||||
int num_pages;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (sclp_vt220_initialized)
|
sclp_vt220_init_count++;
|
||||||
|
if (sclp_vt220_init_count != 1)
|
||||||
return 0;
|
return 0;
|
||||||
sclp_vt220_initialized = 1;
|
|
||||||
spin_lock_init(&sclp_vt220_lock);
|
spin_lock_init(&sclp_vt220_lock);
|
||||||
INIT_LIST_HEAD(&sclp_vt220_empty);
|
INIT_LIST_HEAD(&sclp_vt220_empty);
|
||||||
INIT_LIST_HEAD(&sclp_vt220_outqueue);
|
INIT_LIST_HEAD(&sclp_vt220_outqueue);
|
||||||
|
@ -649,24 +656,22 @@ static int __init __sclp_vt220_init(void)
|
||||||
sclp_vt220_flush_later = 0;
|
sclp_vt220_flush_later = 0;
|
||||||
|
|
||||||
/* Allocate pages for output buffering */
|
/* Allocate pages for output buffering */
|
||||||
num_pages = slab_is_available() ? MAX_KMEM_PAGES : MAX_CONSOLE_PAGES;
|
|
||||||
for (i = 0; i < num_pages; i++) {
|
for (i = 0; i < num_pages; i++) {
|
||||||
if (slab_is_available())
|
if (slab_is_available())
|
||||||
page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||||
else
|
else
|
||||||
page = alloc_bootmem_low_pages(PAGE_SIZE);
|
page = alloc_bootmem_low_pages(PAGE_SIZE);
|
||||||
if (!page) {
|
if (!page) {
|
||||||
__sclp_vt220_cleanup();
|
rc = -ENOMEM;
|
||||||
return -ENOMEM;
|
goto out;
|
||||||
}
|
}
|
||||||
list_add_tail((struct list_head *) page, &sclp_vt220_empty);
|
list_add_tail((struct list_head *) page, &sclp_vt220_empty);
|
||||||
}
|
}
|
||||||
rc = sclp_register(&sclp_vt220_register);
|
rc = sclp_register(&sclp_vt220_register);
|
||||||
|
out:
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_ERR SCLP_VT220_PRINT_HEADER
|
__sclp_vt220_free_pages();
|
||||||
"could not register vt220 - "
|
sclp_vt220_init_count--;
|
||||||
"sclp_register returned %d\n", rc);
|
|
||||||
__sclp_vt220_cleanup();
|
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -689,15 +694,13 @@ static int __init sclp_vt220_tty_init(void)
|
||||||
{
|
{
|
||||||
struct tty_driver *driver;
|
struct tty_driver *driver;
|
||||||
int rc;
|
int rc;
|
||||||
int cleanup;
|
|
||||||
|
|
||||||
/* Note: we're not testing for CONSOLE_IS_SCLP here to preserve
|
/* Note: we're not testing for CONSOLE_IS_SCLP here to preserve
|
||||||
* symmetry between VM and LPAR systems regarding ttyS1. */
|
* symmetry between VM and LPAR systems regarding ttyS1. */
|
||||||
driver = alloc_tty_driver(1);
|
driver = alloc_tty_driver(1);
|
||||||
if (!driver)
|
if (!driver)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
cleanup = !sclp_vt220_initialized;
|
rc = __sclp_vt220_init(MAX_KMEM_PAGES);
|
||||||
rc = __sclp_vt220_init();
|
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out_driver;
|
goto out_driver;
|
||||||
|
|
||||||
|
@ -723,8 +726,7 @@ static int __init sclp_vt220_tty_init(void)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_init:
|
out_init:
|
||||||
if (cleanup)
|
__sclp_vt220_cleanup();
|
||||||
__sclp_vt220_cleanup();
|
|
||||||
out_driver:
|
out_driver:
|
||||||
put_tty_driver(driver);
|
put_tty_driver(driver);
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -773,10 +775,9 @@ sclp_vt220_con_init(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&sclp_vt220_register.list);
|
|
||||||
if (!CONSOLE_IS_SCLP)
|
if (!CONSOLE_IS_SCLP)
|
||||||
return 0;
|
return 0;
|
||||||
rc = __sclp_vt220_init();
|
rc = __sclp_vt220_init(MAX_CONSOLE_PAGES);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
/* Attach linux console */
|
/* Attach linux console */
|
||||||
|
|
Loading…
Reference in a new issue