diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2007-07-27 06:29:22 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2007-07-27 06:29:20 -0400 |
commit | 5aaaf9f0ed11882fe7c6bc4202f78da1baa8caba (patch) | |
tree | f1e9cbe1a2d4a05f8fba14c6e3b9c2d3928ecc8f /drivers/s390/char | |
parent | 4434a38c37dd30e5cd01456a136367a43d8da2dd (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.c | 61 |
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 | */ |
624 | static int __init_refok __sclp_vt220_init(int early) | 624 | static 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 | |||
637 | static 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 | */ |
670 | static int __init | 687 | static int __init sclp_vt220_tty_init(void) |
671 | sclp_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 | ||
718 | module_init(sclp_vt220_tty_init); | 729 | out_sclp: |
730 | sclp_unregister(&sclp_vt220_register); | ||
731 | out_init: | ||
732 | __sclp_vt220_cleanup(); | ||
733 | out_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 */ |