From 77b6f3b417e5fb499b2dc1e7cb0c0340fda4a214 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Mon, 14 Jul 2008 09:59:07 +0200 Subject: [PATCH] --- yaml --- r: 98975 b: refs/heads/master c: ad211790c040fae3459e9c4c8cbd681ae126d2b8 h: refs/heads/master i: 98973: 5a80aa609be8400e22a8c12b2880c5b0bcb0a8ad 98971: 4e696cc1d0036c924f845718a81432126fd64a3e 98967: ce159be2931a2787269358a478de181e66b9da7e 98959: a8bfc1e12f48e6b4df0f15af2bc6d724343d3520 98943: 63c9f5c8b783a37d819342b4ff16c6b65d43df8e v: v3 --- [refs] | 2 +- trunk/drivers/s390/char/sclp_vt220.c | 55 ++++++++++++++-------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/[refs] b/[refs] index 37b8c83eb65a..03604ebaf3bc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 773922e1dab93a62e60cfb34afadb0f66d5f12e9 +refs/heads/master: ad211790c040fae3459e9c4c8cbd681ae126d2b8 diff --git a/trunk/drivers/s390/char/sclp_vt220.c b/trunk/drivers/s390/char/sclp_vt220.c index 3e577f655b18..baea4d548523 100644 --- a/trunk/drivers/s390/char/sclp_vt220.c +++ b/trunk/drivers/s390/char/sclp_vt220.c @@ -82,8 +82,8 @@ static struct sclp_vt220_request *sclp_vt220_current_request; /* Number of characters in current request buffer */ static int sclp_vt220_buffered_chars; -/* Flag indicating whether this driver has already been initialized */ -static int sclp_vt220_initialized = 0; +/* Counter controlling core driver initialization. */ +static int __initdata sclp_vt220_init_count; /* Flag indicating that sclp_vt220_current_request should really * 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(); } -/* - * Initialize all relevant components and register driver with system. - */ -static void __init __sclp_vt220_cleanup(void) +/* Release allocated pages. */ +static void __init __sclp_vt220_free_pages(void) { struct list_head *page, *p; @@ -623,21 +621,30 @@ 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) +/* 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; int i; - int num_pages; int rc; - if (sclp_vt220_initialized) + sclp_vt220_init_count++; + if (sclp_vt220_init_count != 1) return 0; - sclp_vt220_initialized = 1; spin_lock_init(&sclp_vt220_lock); INIT_LIST_HEAD(&sclp_vt220_empty); INIT_LIST_HEAD(&sclp_vt220_outqueue); @@ -649,24 +656,22 @@ static int __init __sclp_vt220_init(void) sclp_vt220_flush_later = 0; /* Allocate pages for output buffering */ - num_pages = slab_is_available() ? MAX_KMEM_PAGES : MAX_CONSOLE_PAGES; for (i = 0; i < num_pages; i++) { if (slab_is_available()) page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); else page = alloc_bootmem_low_pages(PAGE_SIZE); if (!page) { - __sclp_vt220_cleanup(); - return -ENOMEM; + rc = -ENOMEM; + goto out; } list_add_tail((struct list_head *) page, &sclp_vt220_empty); } rc = sclp_register(&sclp_vt220_register); +out: if (rc) { - printk(KERN_ERR SCLP_VT220_PRINT_HEADER - "could not register vt220 - " - "sclp_register returned %d\n", rc); - __sclp_vt220_cleanup(); + __sclp_vt220_free_pages(); + sclp_vt220_init_count--; } return rc; } @@ -689,15 +694,13 @@ 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(); + rc = __sclp_vt220_init(MAX_KMEM_PAGES); if (rc) goto out_driver; @@ -723,8 +726,7 @@ static int __init sclp_vt220_tty_init(void) return 0; out_init: - if (cleanup) - __sclp_vt220_cleanup(); + __sclp_vt220_cleanup(); out_driver: put_tty_driver(driver); return rc; @@ -773,10 +775,9 @@ sclp_vt220_con_init(void) { int rc; - INIT_LIST_HEAD(&sclp_vt220_register.list); if (!CONSOLE_IS_SCLP) return 0; - rc = __sclp_vt220_init(); + rc = __sclp_vt220_init(MAX_CONSOLE_PAGES); if (rc) return rc; /* Attach linux console */