aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2007-07-27 06:29:22 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2007-07-27 06:29:20 -0400
commit5aaaf9f0ed11882fe7c6bc4202f78da1baa8caba (patch)
treef1e9cbe1a2d4a05f8fba14c6e3b9c2d3928ecc8f /drivers/s390/char
parent4434a38c37dd30e5cd01456a136367a43d8da2dd (diff)
[S390] Fix sclp_vt220 error handling.
Also convert to slab_is_available() as an indicator if get_zeroed_page() will work or not. Signed-off-by: Heiko Carstens <heiko.carstens@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.c61
1 files changed, 40 insertions, 21 deletions
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 36fed6630f2e..40cd21bc5cc4 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -621,10 +621,24 @@ sclp_vt220_flush_buffer(struct tty_struct *tty)
621/* 621/*
622 * Initialize all relevant components and register driver with system. 622 * Initialize all relevant components and register driver with system.
623 */ 623 */
624static int __init_refok __sclp_vt220_init(int early) 624static void __init __sclp_vt220_cleanup(void)
625{
626 struct list_head *page, *p;
627
628 list_for_each_safe(page, p, &sclp_vt220_empty) {
629 list_del(page);
630 if (slab_is_available())
631 free_page((unsigned long) page);
632 else
633 free_bootmem((unsigned long) page, PAGE_SIZE);
634 }
635}
636
637static int __init __sclp_vt220_init(void)
625{ 638{
626 void *page; 639 void *page;
627 int i; 640 int i;
641 int num_pages;
628 642
629 if (sclp_vt220_initialized) 643 if (sclp_vt220_initialized)
630 return 0; 644 return 0;
@@ -641,13 +655,16 @@ static int __init_refok __sclp_vt220_init(int early)
641 sclp_vt220_flush_later = 0; 655 sclp_vt220_flush_later = 0;
642 656
643 /* Allocate pages for output buffering */ 657 /* Allocate pages for output buffering */
644 for (i = 0; i < (early ? MAX_CONSOLE_PAGES : MAX_KMEM_PAGES); i++) { 658 num_pages = slab_is_available() ? MAX_KMEM_PAGES : MAX_CONSOLE_PAGES;
645 if (early) 659 for (i = 0; i < num_pages; i++) {
646 page = alloc_bootmem_low_pages(PAGE_SIZE); 660 if (slab_is_available())
647 else
648 page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 661 page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
649 if (!page) 662 else
663 page = alloc_bootmem_low_pages(PAGE_SIZE);
664 if (!page) {
665 __sclp_vt220_cleanup();
650 return -ENOMEM; 666 return -ENOMEM;
667 }
651 list_add_tail((struct list_head *) page, &sclp_vt220_empty); 668 list_add_tail((struct list_head *) page, &sclp_vt220_empty);
652 } 669 }
653 return 0; 670 return 0;
@@ -661,14 +678,13 @@ static const struct tty_operations sclp_vt220_ops = {
661 .flush_chars = sclp_vt220_flush_chars, 678 .flush_chars = sclp_vt220_flush_chars,
662 .write_room = sclp_vt220_write_room, 679 .write_room = sclp_vt220_write_room,
663 .chars_in_buffer = sclp_vt220_chars_in_buffer, 680 .chars_in_buffer = sclp_vt220_chars_in_buffer,
664 .flush_buffer = sclp_vt220_flush_buffer 681 .flush_buffer = sclp_vt220_flush_buffer,
665}; 682};
666 683
667/* 684/*
668 * Register driver with SCLP and Linux and initialize internal tty structures. 685 * Register driver with SCLP and Linux and initialize internal tty structures.
669 */ 686 */
670static int __init 687static int __init sclp_vt220_tty_init(void)
671sclp_vt220_tty_init(void)
672{ 688{
673 struct tty_driver *driver; 689 struct tty_driver *driver;
674 int rc; 690 int rc;
@@ -678,18 +694,15 @@ sclp_vt220_tty_init(void)
678 driver = alloc_tty_driver(1); 694 driver = alloc_tty_driver(1);
679 if (!driver) 695 if (!driver)
680 return -ENOMEM; 696 return -ENOMEM;
681 rc = __sclp_vt220_init(0); 697 rc = __sclp_vt220_init();
682 if (rc) { 698 if (rc)
683 put_tty_driver(driver); 699 goto out_driver;
684 return rc;
685 }
686 rc = sclp_register(&sclp_vt220_register); 700 rc = sclp_register(&sclp_vt220_register);
687 if (rc) { 701 if (rc) {
688 printk(KERN_ERR SCLP_VT220_PRINT_HEADER 702 printk(KERN_ERR SCLP_VT220_PRINT_HEADER
689 "could not register tty - " 703 "could not register tty - "
690 "sclp_register returned %d\n", rc); 704 "sclp_register returned %d\n", rc);
691 put_tty_driver(driver); 705 goto out_init;
692 return rc;
693 } 706 }
694 707
695 driver->owner = THIS_MODULE; 708 driver->owner = THIS_MODULE;
@@ -708,14 +721,20 @@ sclp_vt220_tty_init(void)
708 printk(KERN_ERR SCLP_VT220_PRINT_HEADER 721 printk(KERN_ERR SCLP_VT220_PRINT_HEADER
709 "could not register tty - " 722 "could not register tty - "
710 "tty_register_driver returned %d\n", rc); 723 "tty_register_driver returned %d\n", rc);
711 put_tty_driver(driver); 724 goto out_sclp;
712 return rc;
713 } 725 }
714 sclp_vt220_driver = driver; 726 sclp_vt220_driver = driver;
715 return 0; 727 return 0;
716}
717 728
718module_init(sclp_vt220_tty_init); 729out_sclp:
730 sclp_unregister(&sclp_vt220_register);
731out_init:
732 __sclp_vt220_cleanup();
733out_driver:
734 put_tty_driver(driver);
735 return rc;
736}
737__initcall(sclp_vt220_tty_init);
719 738
720#ifdef CONFIG_SCLP_VT220_CONSOLE 739#ifdef CONFIG_SCLP_VT220_CONSOLE
721 740
@@ -761,7 +780,7 @@ sclp_vt220_con_init(void)
761 780
762 if (!CONSOLE_IS_SCLP) 781 if (!CONSOLE_IS_SCLP)
763 return 0; 782 return 0;
764 rc = __sclp_vt220_init(1); 783 rc = __sclp_vt220_init();
765 if (rc) 784 if (rc)
766 return rc; 785 return rc;
767 /* Attach linux console */ 786 /* Attach linux console */