diff options
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r-- | drivers/char/tty_io.c | 463 |
1 files changed, 306 insertions, 157 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index e94bee032314..82f6a8c86332 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -95,8 +95,9 @@ | |||
95 | #include <linux/wait.h> | 95 | #include <linux/wait.h> |
96 | #include <linux/bitops.h> | 96 | #include <linux/bitops.h> |
97 | #include <linux/delay.h> | 97 | #include <linux/delay.h> |
98 | #include <linux/seq_file.h> | ||
98 | 99 | ||
99 | #include <asm/uaccess.h> | 100 | #include <linux/uaccess.h> |
100 | #include <asm/system.h> | 101 | #include <asm/system.h> |
101 | 102 | ||
102 | #include <linux/kbd_kern.h> | 103 | #include <linux/kbd_kern.h> |
@@ -682,7 +683,7 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | |||
682 | static DEFINE_SPINLOCK(tty_ldisc_lock); | 683 | static DEFINE_SPINLOCK(tty_ldisc_lock); |
683 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); | 684 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); |
684 | /* Line disc dispatch table */ | 685 | /* Line disc dispatch table */ |
685 | static struct tty_ldisc tty_ldiscs[NR_LDISCS]; | 686 | static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; |
686 | 687 | ||
687 | /** | 688 | /** |
688 | * tty_register_ldisc - install a line discipline | 689 | * tty_register_ldisc - install a line discipline |
@@ -697,7 +698,7 @@ static struct tty_ldisc tty_ldiscs[NR_LDISCS]; | |||
697 | * takes tty_ldisc_lock to guard against ldisc races | 698 | * takes tty_ldisc_lock to guard against ldisc races |
698 | */ | 699 | */ |
699 | 700 | ||
700 | int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) | 701 | int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc) |
701 | { | 702 | { |
702 | unsigned long flags; | 703 | unsigned long flags; |
703 | int ret = 0; | 704 | int ret = 0; |
@@ -706,10 +707,9 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) | |||
706 | return -EINVAL; | 707 | return -EINVAL; |
707 | 708 | ||
708 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 709 | spin_lock_irqsave(&tty_ldisc_lock, flags); |
709 | tty_ldiscs[disc] = *new_ldisc; | 710 | tty_ldiscs[disc] = new_ldisc; |
710 | tty_ldiscs[disc].num = disc; | 711 | new_ldisc->num = disc; |
711 | tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; | 712 | new_ldisc->refcount = 0; |
712 | tty_ldiscs[disc].refcount = 0; | ||
713 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 713 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
714 | 714 | ||
715 | return ret; | 715 | return ret; |
@@ -737,19 +737,56 @@ int tty_unregister_ldisc(int disc) | |||
737 | return -EINVAL; | 737 | return -EINVAL; |
738 | 738 | ||
739 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 739 | spin_lock_irqsave(&tty_ldisc_lock, flags); |
740 | if (tty_ldiscs[disc].refcount) | 740 | if (tty_ldiscs[disc]->refcount) |
741 | ret = -EBUSY; | 741 | ret = -EBUSY; |
742 | else | 742 | else |
743 | tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED; | 743 | tty_ldiscs[disc] = NULL; |
744 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 744 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
745 | 745 | ||
746 | return ret; | 746 | return ret; |
747 | } | 747 | } |
748 | EXPORT_SYMBOL(tty_unregister_ldisc); | 748 | EXPORT_SYMBOL(tty_unregister_ldisc); |
749 | 749 | ||
750 | |||
751 | /** | ||
752 | * tty_ldisc_try_get - try and reference an ldisc | ||
753 | * @disc: ldisc number | ||
754 | * @ld: tty ldisc structure to complete | ||
755 | * | ||
756 | * Attempt to open and lock a line discipline into place. Return | ||
757 | * the line discipline refcounted and assigned in ld. On an error | ||
758 | * report the error code back | ||
759 | */ | ||
760 | |||
761 | static int tty_ldisc_try_get(int disc, struct tty_ldisc *ld) | ||
762 | { | ||
763 | unsigned long flags; | ||
764 | struct tty_ldisc_ops *ldops; | ||
765 | int err = -EINVAL; | ||
766 | |||
767 | spin_lock_irqsave(&tty_ldisc_lock, flags); | ||
768 | ld->ops = NULL; | ||
769 | ldops = tty_ldiscs[disc]; | ||
770 | /* Check the entry is defined */ | ||
771 | if (ldops) { | ||
772 | /* If the module is being unloaded we can't use it */ | ||
773 | if (!try_module_get(ldops->owner)) | ||
774 | err = -EAGAIN; | ||
775 | else { | ||
776 | /* lock it */ | ||
777 | ldops->refcount++; | ||
778 | ld->ops = ldops; | ||
779 | err = 0; | ||
780 | } | ||
781 | } | ||
782 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | ||
783 | return err; | ||
784 | } | ||
785 | |||
750 | /** | 786 | /** |
751 | * tty_ldisc_get - take a reference to an ldisc | 787 | * tty_ldisc_get - take a reference to an ldisc |
752 | * @disc: ldisc number | 788 | * @disc: ldisc number |
789 | * @ld: tty line discipline structure to use | ||
753 | * | 790 | * |
754 | * Takes a reference to a line discipline. Deals with refcounts and | 791 | * Takes a reference to a line discipline. Deals with refcounts and |
755 | * module locking counts. Returns NULL if the discipline is not available. | 792 | * module locking counts. Returns NULL if the discipline is not available. |
@@ -760,32 +797,20 @@ EXPORT_SYMBOL(tty_unregister_ldisc); | |||
760 | * takes tty_ldisc_lock to guard against ldisc races | 797 | * takes tty_ldisc_lock to guard against ldisc races |
761 | */ | 798 | */ |
762 | 799 | ||
763 | struct tty_ldisc *tty_ldisc_get(int disc) | 800 | static int tty_ldisc_get(int disc, struct tty_ldisc *ld) |
764 | { | 801 | { |
765 | unsigned long flags; | 802 | int err; |
766 | struct tty_ldisc *ld; | ||
767 | 803 | ||
768 | if (disc < N_TTY || disc >= NR_LDISCS) | 804 | if (disc < N_TTY || disc >= NR_LDISCS) |
769 | return NULL; | 805 | return -EINVAL; |
770 | 806 | err = tty_ldisc_try_get(disc, ld); | |
771 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 807 | if (err == -EAGAIN) { |
772 | 808 | request_module("tty-ldisc-%d", disc); | |
773 | ld = &tty_ldiscs[disc]; | 809 | err = tty_ldisc_try_get(disc, ld); |
774 | /* Check the entry is defined */ | 810 | } |
775 | if (ld->flags & LDISC_FLAG_DEFINED) { | 811 | return err; |
776 | /* If the module is being unloaded we can't use it */ | ||
777 | if (!try_module_get(ld->owner)) | ||
778 | ld = NULL; | ||
779 | else /* lock it */ | ||
780 | ld->refcount++; | ||
781 | } else | ||
782 | ld = NULL; | ||
783 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | ||
784 | return ld; | ||
785 | } | 812 | } |
786 | 813 | ||
787 | EXPORT_SYMBOL_GPL(tty_ldisc_get); | ||
788 | |||
789 | /** | 814 | /** |
790 | * tty_ldisc_put - drop ldisc reference | 815 | * tty_ldisc_put - drop ldisc reference |
791 | * @disc: ldisc number | 816 | * @disc: ldisc number |
@@ -797,22 +822,67 @@ EXPORT_SYMBOL_GPL(tty_ldisc_get); | |||
797 | * takes tty_ldisc_lock to guard against ldisc races | 822 | * takes tty_ldisc_lock to guard against ldisc races |
798 | */ | 823 | */ |
799 | 824 | ||
800 | void tty_ldisc_put(int disc) | 825 | static void tty_ldisc_put(struct tty_ldisc_ops *ld) |
801 | { | 826 | { |
802 | struct tty_ldisc *ld; | ||
803 | unsigned long flags; | 827 | unsigned long flags; |
828 | int disc = ld->num; | ||
804 | 829 | ||
805 | BUG_ON(disc < N_TTY || disc >= NR_LDISCS); | 830 | BUG_ON(disc < N_TTY || disc >= NR_LDISCS); |
806 | 831 | ||
807 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 832 | spin_lock_irqsave(&tty_ldisc_lock, flags); |
808 | ld = &tty_ldiscs[disc]; | 833 | ld = tty_ldiscs[disc]; |
809 | BUG_ON(ld->refcount == 0); | 834 | BUG_ON(ld->refcount == 0); |
810 | ld->refcount--; | 835 | ld->refcount--; |
811 | module_put(ld->owner); | 836 | module_put(ld->owner); |
812 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 837 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
813 | } | 838 | } |
814 | 839 | ||
815 | EXPORT_SYMBOL_GPL(tty_ldisc_put); | 840 | static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos) |
841 | { | ||
842 | return (*pos < NR_LDISCS) ? pos : NULL; | ||
843 | } | ||
844 | |||
845 | static void * tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos) | ||
846 | { | ||
847 | (*pos)++; | ||
848 | return (*pos < NR_LDISCS) ? pos : NULL; | ||
849 | } | ||
850 | |||
851 | static void tty_ldiscs_seq_stop(struct seq_file *m, void *v) | ||
852 | { | ||
853 | } | ||
854 | |||
855 | static int tty_ldiscs_seq_show(struct seq_file *m, void *v) | ||
856 | { | ||
857 | int i = *(loff_t *)v; | ||
858 | struct tty_ldisc ld; | ||
859 | |||
860 | if (tty_ldisc_get(i, &ld) < 0) | ||
861 | return 0; | ||
862 | seq_printf(m, "%-10s %2d\n", ld.ops->name ? ld.ops->name : "???", i); | ||
863 | tty_ldisc_put(ld.ops); | ||
864 | return 0; | ||
865 | } | ||
866 | |||
867 | static const struct seq_operations tty_ldiscs_seq_ops = { | ||
868 | .start = tty_ldiscs_seq_start, | ||
869 | .next = tty_ldiscs_seq_next, | ||
870 | .stop = tty_ldiscs_seq_stop, | ||
871 | .show = tty_ldiscs_seq_show, | ||
872 | }; | ||
873 | |||
874 | static int proc_tty_ldiscs_open(struct inode *inode, struct file *file) | ||
875 | { | ||
876 | return seq_open(file, &tty_ldiscs_seq_ops); | ||
877 | } | ||
878 | |||
879 | const struct file_operations tty_ldiscs_proc_fops = { | ||
880 | .owner = THIS_MODULE, | ||
881 | .open = proc_tty_ldiscs_open, | ||
882 | .read = seq_read, | ||
883 | .llseek = seq_lseek, | ||
884 | .release = seq_release, | ||
885 | }; | ||
816 | 886 | ||
817 | /** | 887 | /** |
818 | * tty_ldisc_assign - set ldisc on a tty | 888 | * tty_ldisc_assign - set ldisc on a tty |
@@ -829,8 +899,8 @@ EXPORT_SYMBOL_GPL(tty_ldisc_put); | |||
829 | 899 | ||
830 | static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) | 900 | static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) |
831 | { | 901 | { |
902 | ld->refcount = 0; | ||
832 | tty->ldisc = *ld; | 903 | tty->ldisc = *ld; |
833 | tty->ldisc.refcount = 0; | ||
834 | } | 904 | } |
835 | 905 | ||
836 | /** | 906 | /** |
@@ -954,6 +1024,41 @@ static void tty_ldisc_enable(struct tty_struct *tty) | |||
954 | } | 1024 | } |
955 | 1025 | ||
956 | /** | 1026 | /** |
1027 | * tty_ldisc_restore - helper for tty ldisc change | ||
1028 | * @tty: tty to recover | ||
1029 | * @old: previous ldisc | ||
1030 | * | ||
1031 | * Restore the previous line discipline or N_TTY when a line discipline | ||
1032 | * change fails due to an open error | ||
1033 | */ | ||
1034 | |||
1035 | static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) | ||
1036 | { | ||
1037 | char buf[64]; | ||
1038 | struct tty_ldisc new_ldisc; | ||
1039 | |||
1040 | /* There is an outstanding reference here so this is safe */ | ||
1041 | tty_ldisc_get(old->ops->num, old); | ||
1042 | tty_ldisc_assign(tty, old); | ||
1043 | tty_set_termios_ldisc(tty, old->ops->num); | ||
1044 | if (old->ops->open && (old->ops->open(tty) < 0)) { | ||
1045 | tty_ldisc_put(old->ops); | ||
1046 | /* This driver is always present */ | ||
1047 | if (tty_ldisc_get(N_TTY, &new_ldisc) < 0) | ||
1048 | panic("n_tty: get"); | ||
1049 | tty_ldisc_assign(tty, &new_ldisc); | ||
1050 | tty_set_termios_ldisc(tty, N_TTY); | ||
1051 | if (new_ldisc.ops->open) { | ||
1052 | int r = new_ldisc.ops->open(tty); | ||
1053 | if (r < 0) | ||
1054 | panic("Couldn't open N_TTY ldisc for " | ||
1055 | "%s --- error %d.", | ||
1056 | tty_name(tty, buf), r); | ||
1057 | } | ||
1058 | } | ||
1059 | } | ||
1060 | |||
1061 | /** | ||
957 | * tty_set_ldisc - set line discipline | 1062 | * tty_set_ldisc - set line discipline |
958 | * @tty: the terminal to set | 1063 | * @tty: the terminal to set |
959 | * @ldisc: the line discipline | 1064 | * @ldisc: the line discipline |
@@ -967,28 +1072,18 @@ static void tty_ldisc_enable(struct tty_struct *tty) | |||
967 | 1072 | ||
968 | static int tty_set_ldisc(struct tty_struct *tty, int ldisc) | 1073 | static int tty_set_ldisc(struct tty_struct *tty, int ldisc) |
969 | { | 1074 | { |
970 | int retval = 0; | 1075 | int retval; |
971 | struct tty_ldisc o_ldisc; | 1076 | struct tty_ldisc o_ldisc, new_ldisc; |
972 | char buf[64]; | ||
973 | int work; | 1077 | int work; |
974 | unsigned long flags; | 1078 | unsigned long flags; |
975 | struct tty_ldisc *ld; | ||
976 | struct tty_struct *o_tty; | 1079 | struct tty_struct *o_tty; |
977 | 1080 | ||
978 | if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS)) | ||
979 | return -EINVAL; | ||
980 | |||
981 | restart: | 1081 | restart: |
982 | 1082 | /* This is a bit ugly for now but means we can break the 'ldisc | |
983 | ld = tty_ldisc_get(ldisc); | 1083 | is part of the tty struct' assumption later */ |
984 | /* Eduardo Blanco <ejbs@cs.cs.com.uy> */ | 1084 | retval = tty_ldisc_get(ldisc, &new_ldisc); |
985 | /* Cyrus Durgin <cider@speakeasy.org> */ | 1085 | if (retval) |
986 | if (ld == NULL) { | 1086 | return retval; |
987 | request_module("tty-ldisc-%d", ldisc); | ||
988 | ld = tty_ldisc_get(ldisc); | ||
989 | } | ||
990 | if (ld == NULL) | ||
991 | return -EINVAL; | ||
992 | 1087 | ||
993 | /* | 1088 | /* |
994 | * Problem: What do we do if this blocks ? | 1089 | * Problem: What do we do if this blocks ? |
@@ -996,8 +1091,8 @@ restart: | |||
996 | 1091 | ||
997 | tty_wait_until_sent(tty, 0); | 1092 | tty_wait_until_sent(tty, 0); |
998 | 1093 | ||
999 | if (tty->ldisc.num == ldisc) { | 1094 | if (tty->ldisc.ops->num == ldisc) { |
1000 | tty_ldisc_put(ldisc); | 1095 | tty_ldisc_put(new_ldisc.ops); |
1001 | return 0; | 1096 | return 0; |
1002 | } | 1097 | } |
1003 | 1098 | ||
@@ -1024,7 +1119,7 @@ restart: | |||
1024 | /* Free the new ldisc we grabbed. Must drop the lock | 1119 | /* Free the new ldisc we grabbed. Must drop the lock |
1025 | first. */ | 1120 | first. */ |
1026 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 1121 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
1027 | tty_ldisc_put(ldisc); | 1122 | tty_ldisc_put(o_ldisc.ops); |
1028 | /* | 1123 | /* |
1029 | * There are several reasons we may be busy, including | 1124 | * There are several reasons we may be busy, including |
1030 | * random momentary I/O traffic. We must therefore | 1125 | * random momentary I/O traffic. We must therefore |
@@ -1038,7 +1133,7 @@ restart: | |||
1038 | } | 1133 | } |
1039 | if (o_tty && o_tty->ldisc.refcount) { | 1134 | if (o_tty && o_tty->ldisc.refcount) { |
1040 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 1135 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
1041 | tty_ldisc_put(ldisc); | 1136 | tty_ldisc_put(o_tty->ldisc.ops); |
1042 | if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0) | 1137 | if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0) |
1043 | return -ERESTARTSYS; | 1138 | return -ERESTARTSYS; |
1044 | goto restart; | 1139 | goto restart; |
@@ -1049,8 +1144,9 @@ restart: | |||
1049 | * another ldisc change | 1144 | * another ldisc change |
1050 | */ | 1145 | */ |
1051 | if (!test_bit(TTY_LDISC, &tty->flags)) { | 1146 | if (!test_bit(TTY_LDISC, &tty->flags)) { |
1147 | struct tty_ldisc *ld; | ||
1052 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 1148 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
1053 | tty_ldisc_put(ldisc); | 1149 | tty_ldisc_put(new_ldisc.ops); |
1054 | ld = tty_ldisc_ref_wait(tty); | 1150 | ld = tty_ldisc_ref_wait(tty); |
1055 | tty_ldisc_deref(ld); | 1151 | tty_ldisc_deref(ld); |
1056 | goto restart; | 1152 | goto restart; |
@@ -1060,7 +1156,7 @@ restart: | |||
1060 | if (o_tty) | 1156 | if (o_tty) |
1061 | clear_bit(TTY_LDISC, &o_tty->flags); | 1157 | clear_bit(TTY_LDISC, &o_tty->flags); |
1062 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 1158 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
1063 | 1159 | ||
1064 | /* | 1160 | /* |
1065 | * From this point on we know nobody has an ldisc | 1161 | * From this point on we know nobody has an ldisc |
1066 | * usage reference, nor can they obtain one until | 1162 | * usage reference, nor can they obtain one until |
@@ -1070,45 +1166,30 @@ restart: | |||
1070 | work = cancel_delayed_work(&tty->buf.work); | 1166 | work = cancel_delayed_work(&tty->buf.work); |
1071 | /* | 1167 | /* |
1072 | * Wait for ->hangup_work and ->buf.work handlers to terminate | 1168 | * Wait for ->hangup_work and ->buf.work handlers to terminate |
1169 | * MUST NOT hold locks here. | ||
1073 | */ | 1170 | */ |
1074 | flush_scheduled_work(); | 1171 | flush_scheduled_work(); |
1075 | /* Shutdown the current discipline. */ | 1172 | /* Shutdown the current discipline. */ |
1076 | if (tty->ldisc.close) | 1173 | if (o_ldisc.ops->close) |
1077 | (tty->ldisc.close)(tty); | 1174 | (o_ldisc.ops->close)(tty); |
1078 | 1175 | ||
1079 | /* Now set up the new line discipline. */ | 1176 | /* Now set up the new line discipline. */ |
1080 | tty_ldisc_assign(tty, ld); | 1177 | tty_ldisc_assign(tty, &new_ldisc); |
1081 | tty_set_termios_ldisc(tty, ldisc); | 1178 | tty_set_termios_ldisc(tty, ldisc); |
1082 | if (tty->ldisc.open) | 1179 | if (new_ldisc.ops->open) |
1083 | retval = (tty->ldisc.open)(tty); | 1180 | retval = (new_ldisc.ops->open)(tty); |
1084 | if (retval < 0) { | 1181 | if (retval < 0) { |
1085 | tty_ldisc_put(ldisc); | 1182 | tty_ldisc_put(new_ldisc.ops); |
1086 | /* There is an outstanding reference here so this is safe */ | 1183 | tty_ldisc_restore(tty, &o_ldisc); |
1087 | tty_ldisc_assign(tty, tty_ldisc_get(o_ldisc.num)); | ||
1088 | tty_set_termios_ldisc(tty, tty->ldisc.num); | ||
1089 | if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) { | ||
1090 | tty_ldisc_put(o_ldisc.num); | ||
1091 | /* This driver is always present */ | ||
1092 | tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); | ||
1093 | tty_set_termios_ldisc(tty, N_TTY); | ||
1094 | if (tty->ldisc.open) { | ||
1095 | int r = tty->ldisc.open(tty); | ||
1096 | |||
1097 | if (r < 0) | ||
1098 | panic("Couldn't open N_TTY ldisc for " | ||
1099 | "%s --- error %d.", | ||
1100 | tty_name(tty, buf), r); | ||
1101 | } | ||
1102 | } | ||
1103 | } | 1184 | } |
1104 | /* At this point we hold a reference to the new ldisc and a | 1185 | /* At this point we hold a reference to the new ldisc and a |
1105 | a reference to the old ldisc. If we ended up flipping back | 1186 | a reference to the old ldisc. If we ended up flipping back |
1106 | to the existing ldisc we have two references to it */ | 1187 | to the existing ldisc we have two references to it */ |
1107 | 1188 | ||
1108 | if (tty->ldisc.num != o_ldisc.num && tty->ops->set_ldisc) | 1189 | if (tty->ldisc.ops->num != o_ldisc.ops->num && tty->ops->set_ldisc) |
1109 | tty->ops->set_ldisc(tty); | 1190 | tty->ops->set_ldisc(tty); |
1110 | 1191 | ||
1111 | tty_ldisc_put(o_ldisc.num); | 1192 | tty_ldisc_put(o_ldisc.ops); |
1112 | 1193 | ||
1113 | /* | 1194 | /* |
1114 | * Allow ldisc referencing to occur as soon as the driver | 1195 | * Allow ldisc referencing to occur as soon as the driver |
@@ -1335,8 +1416,8 @@ void tty_wakeup(struct tty_struct *tty) | |||
1335 | if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) { | 1416 | if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) { |
1336 | ld = tty_ldisc_ref(tty); | 1417 | ld = tty_ldisc_ref(tty); |
1337 | if (ld) { | 1418 | if (ld) { |
1338 | if (ld->write_wakeup) | 1419 | if (ld->ops->write_wakeup) |
1339 | ld->write_wakeup(tty); | 1420 | ld->ops->write_wakeup(tty); |
1340 | tty_ldisc_deref(ld); | 1421 | tty_ldisc_deref(ld); |
1341 | } | 1422 | } |
1342 | } | 1423 | } |
@@ -1357,8 +1438,8 @@ void tty_ldisc_flush(struct tty_struct *tty) | |||
1357 | { | 1438 | { |
1358 | struct tty_ldisc *ld = tty_ldisc_ref(tty); | 1439 | struct tty_ldisc *ld = tty_ldisc_ref(tty); |
1359 | if (ld) { | 1440 | if (ld) { |
1360 | if (ld->flush_buffer) | 1441 | if (ld->ops->flush_buffer) |
1361 | ld->flush_buffer(tty); | 1442 | ld->ops->flush_buffer(tty); |
1362 | tty_ldisc_deref(ld); | 1443 | tty_ldisc_deref(ld); |
1363 | } | 1444 | } |
1364 | tty_buffer_flush(tty); | 1445 | tty_buffer_flush(tty); |
@@ -1386,7 +1467,7 @@ static void tty_reset_termios(struct tty_struct *tty) | |||
1386 | * do_tty_hangup - actual handler for hangup events | 1467 | * do_tty_hangup - actual handler for hangup events |
1387 | * @work: tty device | 1468 | * @work: tty device |
1388 | * | 1469 | * |
1389 | * This can be called by the "eventd" kernel thread. That is process | 1470 | k * This can be called by the "eventd" kernel thread. That is process |
1390 | * synchronous but doesn't hold any locks, so we need to make sure we | 1471 | * synchronous but doesn't hold any locks, so we need to make sure we |
1391 | * have the appropriate locks for what we're doing. | 1472 | * have the appropriate locks for what we're doing. |
1392 | * | 1473 | * |
@@ -1449,14 +1530,14 @@ static void do_tty_hangup(struct work_struct *work) | |||
1449 | ld = tty_ldisc_ref(tty); | 1530 | ld = tty_ldisc_ref(tty); |
1450 | if (ld != NULL) { | 1531 | if (ld != NULL) { |
1451 | /* We may have no line discipline at this point */ | 1532 | /* We may have no line discipline at this point */ |
1452 | if (ld->flush_buffer) | 1533 | if (ld->ops->flush_buffer) |
1453 | ld->flush_buffer(tty); | 1534 | ld->ops->flush_buffer(tty); |
1454 | tty_driver_flush_buffer(tty); | 1535 | tty_driver_flush_buffer(tty); |
1455 | if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && | 1536 | if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && |
1456 | ld->write_wakeup) | 1537 | ld->ops->write_wakeup) |
1457 | ld->write_wakeup(tty); | 1538 | ld->ops->write_wakeup(tty); |
1458 | if (ld->hangup) | 1539 | if (ld->ops->hangup) |
1459 | ld->hangup(tty); | 1540 | ld->ops->hangup(tty); |
1460 | } | 1541 | } |
1461 | /* | 1542 | /* |
1462 | * FIXME: Once we trust the LDISC code better we can wait here for | 1543 | * FIXME: Once we trust the LDISC code better we can wait here for |
@@ -1825,8 +1906,8 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
1825 | /* We want to wait for the line discipline to sort out in this | 1906 | /* We want to wait for the line discipline to sort out in this |
1826 | situation */ | 1907 | situation */ |
1827 | ld = tty_ldisc_ref_wait(tty); | 1908 | ld = tty_ldisc_ref_wait(tty); |
1828 | if (ld->read) | 1909 | if (ld->ops->read) |
1829 | i = (ld->read)(tty, file, buf, count); | 1910 | i = (ld->ops->read)(tty, file, buf, count); |
1830 | else | 1911 | else |
1831 | i = -EIO; | 1912 | i = -EIO; |
1832 | tty_ldisc_deref(ld); | 1913 | tty_ldisc_deref(ld); |
@@ -1978,10 +2059,10 @@ static ssize_t tty_write(struct file *file, const char __user *buf, | |||
1978 | printk(KERN_ERR "tty driver %s lacks a write_room method.\n", | 2059 | printk(KERN_ERR "tty driver %s lacks a write_room method.\n", |
1979 | tty->driver->name); | 2060 | tty->driver->name); |
1980 | ld = tty_ldisc_ref_wait(tty); | 2061 | ld = tty_ldisc_ref_wait(tty); |
1981 | if (!ld->write) | 2062 | if (!ld->ops->write) |
1982 | ret = -EIO; | 2063 | ret = -EIO; |
1983 | else | 2064 | else |
1984 | ret = do_tty_write(ld->write, tty, file, buf, count); | 2065 | ret = do_tty_write(ld->ops->write, tty, file, buf, count); |
1985 | tty_ldisc_deref(ld); | 2066 | tty_ldisc_deref(ld); |
1986 | return ret; | 2067 | return ret; |
1987 | } | 2068 | } |
@@ -2007,6 +2088,42 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf, | |||
2007 | return tty_write(file, buf, count, ppos); | 2088 | return tty_write(file, buf, count, ppos); |
2008 | } | 2089 | } |
2009 | 2090 | ||
2091 | void tty_port_init(struct tty_port *port) | ||
2092 | { | ||
2093 | memset(port, 0, sizeof(*port)); | ||
2094 | init_waitqueue_head(&port->open_wait); | ||
2095 | init_waitqueue_head(&port->close_wait); | ||
2096 | mutex_init(&port->mutex); | ||
2097 | port->close_delay = (50 * HZ) / 100; | ||
2098 | port->closing_wait = (3000 * HZ) / 100; | ||
2099 | } | ||
2100 | EXPORT_SYMBOL(tty_port_init); | ||
2101 | |||
2102 | int tty_port_alloc_xmit_buf(struct tty_port *port) | ||
2103 | { | ||
2104 | /* We may sleep in get_zeroed_page() */ | ||
2105 | mutex_lock(&port->mutex); | ||
2106 | if (port->xmit_buf == NULL) | ||
2107 | port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL); | ||
2108 | mutex_unlock(&port->mutex); | ||
2109 | if (port->xmit_buf == NULL) | ||
2110 | return -ENOMEM; | ||
2111 | return 0; | ||
2112 | } | ||
2113 | EXPORT_SYMBOL(tty_port_alloc_xmit_buf); | ||
2114 | |||
2115 | void tty_port_free_xmit_buf(struct tty_port *port) | ||
2116 | { | ||
2117 | mutex_lock(&port->mutex); | ||
2118 | if (port->xmit_buf != NULL) { | ||
2119 | free_page((unsigned long)port->xmit_buf); | ||
2120 | port->xmit_buf = NULL; | ||
2121 | } | ||
2122 | mutex_unlock(&port->mutex); | ||
2123 | } | ||
2124 | EXPORT_SYMBOL(tty_port_free_xmit_buf); | ||
2125 | |||
2126 | |||
2010 | static char ptychar[] = "pqrstuvwxyzabcde"; | 2127 | static char ptychar[] = "pqrstuvwxyzabcde"; |
2011 | 2128 | ||
2012 | /** | 2129 | /** |
@@ -2076,6 +2193,7 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
2076 | struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; | 2193 | struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; |
2077 | struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; | 2194 | struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; |
2078 | int retval = 0; | 2195 | int retval = 0; |
2196 | struct tty_ldisc *ld; | ||
2079 | 2197 | ||
2080 | /* check whether we're reopening an existing tty */ | 2198 | /* check whether we're reopening an existing tty */ |
2081 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { | 2199 | if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { |
@@ -2224,17 +2342,19 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
2224 | * If we fail here just call release_tty to clean up. No need | 2342 | * If we fail here just call release_tty to clean up. No need |
2225 | * to decrement the use counts, as release_tty doesn't care. | 2343 | * to decrement the use counts, as release_tty doesn't care. |
2226 | */ | 2344 | */ |
2345 | |||
2346 | ld = &tty->ldisc; | ||
2227 | 2347 | ||
2228 | if (tty->ldisc.open) { | 2348 | if (ld->ops->open) { |
2229 | retval = (tty->ldisc.open)(tty); | 2349 | retval = (ld->ops->open)(tty); |
2230 | if (retval) | 2350 | if (retval) |
2231 | goto release_mem_out; | 2351 | goto release_mem_out; |
2232 | } | 2352 | } |
2233 | if (o_tty && o_tty->ldisc.open) { | 2353 | if (o_tty && o_tty->ldisc.ops->open) { |
2234 | retval = (o_tty->ldisc.open)(o_tty); | 2354 | retval = (o_tty->ldisc.ops->open)(o_tty); |
2235 | if (retval) { | 2355 | if (retval) { |
2236 | if (tty->ldisc.close) | 2356 | if (ld->ops->close) |
2237 | (tty->ldisc.close)(tty); | 2357 | (ld->ops->close)(tty); |
2238 | goto release_mem_out; | 2358 | goto release_mem_out; |
2239 | } | 2359 | } |
2240 | tty_ldisc_enable(o_tty); | 2360 | tty_ldisc_enable(o_tty); |
@@ -2378,6 +2498,7 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
2378 | static void release_dev(struct file *filp) | 2498 | static void release_dev(struct file *filp) |
2379 | { | 2499 | { |
2380 | struct tty_struct *tty, *o_tty; | 2500 | struct tty_struct *tty, *o_tty; |
2501 | struct tty_ldisc ld; | ||
2381 | int pty_master, tty_closing, o_tty_closing, do_sleep; | 2502 | int pty_master, tty_closing, o_tty_closing, do_sleep; |
2382 | int devpts; | 2503 | int devpts; |
2383 | int idx; | 2504 | int idx; |
@@ -2611,26 +2732,27 @@ static void release_dev(struct file *filp) | |||
2611 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | 2732 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
2612 | /* | 2733 | /* |
2613 | * Shutdown the current line discipline, and reset it to N_TTY. | 2734 | * Shutdown the current line discipline, and reset it to N_TTY. |
2614 | * N.B. why reset ldisc when we're releasing the memory?? | ||
2615 | * | 2735 | * |
2616 | * FIXME: this MUST get fixed for the new reflocking | 2736 | * FIXME: this MUST get fixed for the new reflocking |
2617 | */ | 2737 | */ |
2618 | if (tty->ldisc.close) | 2738 | if (tty->ldisc.ops->close) |
2619 | (tty->ldisc.close)(tty); | 2739 | (tty->ldisc.ops->close)(tty); |
2620 | tty_ldisc_put(tty->ldisc.num); | 2740 | tty_ldisc_put(tty->ldisc.ops); |
2621 | 2741 | ||
2622 | /* | 2742 | /* |
2623 | * Switch the line discipline back | 2743 | * Switch the line discipline back |
2624 | */ | 2744 | */ |
2625 | tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); | 2745 | WARN_ON(tty_ldisc_get(N_TTY, &ld)); |
2746 | tty_ldisc_assign(tty, &ld); | ||
2626 | tty_set_termios_ldisc(tty, N_TTY); | 2747 | tty_set_termios_ldisc(tty, N_TTY); |
2627 | if (o_tty) { | 2748 | if (o_tty) { |
2628 | /* FIXME: could o_tty be in setldisc here ? */ | 2749 | /* FIXME: could o_tty be in setldisc here ? */ |
2629 | clear_bit(TTY_LDISC, &o_tty->flags); | 2750 | clear_bit(TTY_LDISC, &o_tty->flags); |
2630 | if (o_tty->ldisc.close) | 2751 | if (o_tty->ldisc.ops->close) |
2631 | (o_tty->ldisc.close)(o_tty); | 2752 | (o_tty->ldisc.ops->close)(o_tty); |
2632 | tty_ldisc_put(o_tty->ldisc.num); | 2753 | tty_ldisc_put(o_tty->ldisc.ops); |
2633 | tty_ldisc_assign(o_tty, tty_ldisc_get(N_TTY)); | 2754 | WARN_ON(tty_ldisc_get(N_TTY, &ld)); |
2755 | tty_ldisc_assign(o_tty, &ld); | ||
2634 | tty_set_termios_ldisc(o_tty, N_TTY); | 2756 | tty_set_termios_ldisc(o_tty, N_TTY); |
2635 | } | 2757 | } |
2636 | /* | 2758 | /* |
@@ -2665,7 +2787,7 @@ static void release_dev(struct file *filp) | |||
2665 | * ->siglock protects ->signal/->sighand | 2787 | * ->siglock protects ->signal/->sighand |
2666 | */ | 2788 | */ |
2667 | 2789 | ||
2668 | static int tty_open(struct inode *inode, struct file *filp) | 2790 | static int __tty_open(struct inode *inode, struct file *filp) |
2669 | { | 2791 | { |
2670 | struct tty_struct *tty; | 2792 | struct tty_struct *tty; |
2671 | int noctty, retval; | 2793 | int noctty, retval; |
@@ -2779,6 +2901,19 @@ got_driver: | |||
2779 | return 0; | 2901 | return 0; |
2780 | } | 2902 | } |
2781 | 2903 | ||
2904 | /* BKL pushdown: scary code avoidance wrapper */ | ||
2905 | static int tty_open(struct inode *inode, struct file *filp) | ||
2906 | { | ||
2907 | int ret; | ||
2908 | |||
2909 | lock_kernel(); | ||
2910 | ret = __tty_open(inode, filp); | ||
2911 | unlock_kernel(); | ||
2912 | return ret; | ||
2913 | } | ||
2914 | |||
2915 | |||
2916 | |||
2782 | #ifdef CONFIG_UNIX98_PTYS | 2917 | #ifdef CONFIG_UNIX98_PTYS |
2783 | /** | 2918 | /** |
2784 | * ptmx_open - open a unix 98 pty master | 2919 | * ptmx_open - open a unix 98 pty master |
@@ -2792,7 +2927,7 @@ got_driver: | |||
2792 | * allocated_ptys_lock handles the list of free pty numbers | 2927 | * allocated_ptys_lock handles the list of free pty numbers |
2793 | */ | 2928 | */ |
2794 | 2929 | ||
2795 | static int ptmx_open(struct inode *inode, struct file *filp) | 2930 | static int __ptmx_open(struct inode *inode, struct file *filp) |
2796 | { | 2931 | { |
2797 | struct tty_struct *tty; | 2932 | struct tty_struct *tty; |
2798 | int retval; | 2933 | int retval; |
@@ -2831,6 +2966,16 @@ out: | |||
2831 | devpts_kill_index(index); | 2966 | devpts_kill_index(index); |
2832 | return retval; | 2967 | return retval; |
2833 | } | 2968 | } |
2969 | |||
2970 | static int ptmx_open(struct inode *inode, struct file *filp) | ||
2971 | { | ||
2972 | int ret; | ||
2973 | |||
2974 | lock_kernel(); | ||
2975 | ret = __ptmx_open(inode, filp); | ||
2976 | unlock_kernel(); | ||
2977 | return ret; | ||
2978 | } | ||
2834 | #endif | 2979 | #endif |
2835 | 2980 | ||
2836 | /** | 2981 | /** |
@@ -2876,8 +3021,8 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) | |||
2876 | return 0; | 3021 | return 0; |
2877 | 3022 | ||
2878 | ld = tty_ldisc_ref_wait(tty); | 3023 | ld = tty_ldisc_ref_wait(tty); |
2879 | if (ld->poll) | 3024 | if (ld->ops->poll) |
2880 | ret = (ld->poll)(tty, filp, wait); | 3025 | ret = (ld->ops->poll)(tty, filp, wait); |
2881 | tty_ldisc_deref(ld); | 3026 | tty_ldisc_deref(ld); |
2882 | return ret; | 3027 | return ret; |
2883 | } | 3028 | } |
@@ -2886,15 +3031,16 @@ static int tty_fasync(int fd, struct file *filp, int on) | |||
2886 | { | 3031 | { |
2887 | struct tty_struct *tty; | 3032 | struct tty_struct *tty; |
2888 | unsigned long flags; | 3033 | unsigned long flags; |
2889 | int retval; | 3034 | int retval = 0; |
2890 | 3035 | ||
3036 | lock_kernel(); | ||
2891 | tty = (struct tty_struct *)filp->private_data; | 3037 | tty = (struct tty_struct *)filp->private_data; |
2892 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) | 3038 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) |
2893 | return 0; | 3039 | goto out; |
2894 | 3040 | ||
2895 | retval = fasync_helper(fd, filp, on, &tty->fasync); | 3041 | retval = fasync_helper(fd, filp, on, &tty->fasync); |
2896 | if (retval <= 0) | 3042 | if (retval <= 0) |
2897 | return retval; | 3043 | goto out; |
2898 | 3044 | ||
2899 | if (on) { | 3045 | if (on) { |
2900 | enum pid_type type; | 3046 | enum pid_type type; |
@@ -2912,12 +3058,15 @@ static int tty_fasync(int fd, struct file *filp, int on) | |||
2912 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); | 3058 | spin_unlock_irqrestore(&tty->ctrl_lock, flags); |
2913 | retval = __f_setown(filp, pid, type, 0); | 3059 | retval = __f_setown(filp, pid, type, 0); |
2914 | if (retval) | 3060 | if (retval) |
2915 | return retval; | 3061 | goto out; |
2916 | } else { | 3062 | } else { |
2917 | if (!tty->fasync && !waitqueue_active(&tty->read_wait)) | 3063 | if (!tty->fasync && !waitqueue_active(&tty->read_wait)) |
2918 | tty->minimum_to_wake = N_TTY_BUF_SIZE; | 3064 | tty->minimum_to_wake = N_TTY_BUF_SIZE; |
2919 | } | 3065 | } |
2920 | return 0; | 3066 | retval = 0; |
3067 | out: | ||
3068 | unlock_kernel(); | ||
3069 | return retval; | ||
2921 | } | 3070 | } |
2922 | 3071 | ||
2923 | /** | 3072 | /** |
@@ -2947,7 +3096,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p) | |||
2947 | if (get_user(ch, p)) | 3096 | if (get_user(ch, p)) |
2948 | return -EFAULT; | 3097 | return -EFAULT; |
2949 | ld = tty_ldisc_ref_wait(tty); | 3098 | ld = tty_ldisc_ref_wait(tty); |
2950 | ld->receive_buf(tty, &ch, &mbz, 1); | 3099 | ld->ops->receive_buf(tty, &ch, &mbz, 1); |
2951 | tty_ldisc_deref(ld); | 3100 | tty_ldisc_deref(ld); |
2952 | return 0; | 3101 | return 0; |
2953 | } | 3102 | } |
@@ -3322,7 +3471,7 @@ static int send_break(struct tty_struct *tty, unsigned int duration) | |||
3322 | msleep_interruptible(duration); | 3471 | msleep_interruptible(duration); |
3323 | tty->ops->break_ctl(tty, 0); | 3472 | tty->ops->break_ctl(tty, 0); |
3324 | tty_write_unlock(tty); | 3473 | tty_write_unlock(tty); |
3325 | if (!signal_pending(current)) | 3474 | if (signal_pending(current)) |
3326 | return -EINTR; | 3475 | return -EINTR; |
3327 | return 0; | 3476 | return 0; |
3328 | } | 3477 | } |
@@ -3368,35 +3517,31 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p | |||
3368 | static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd, | 3517 | static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd, |
3369 | unsigned __user *p) | 3518 | unsigned __user *p) |
3370 | { | 3519 | { |
3371 | int retval = -EINVAL; | 3520 | int retval; |
3372 | 3521 | unsigned int set, clear, val; | |
3373 | if (tty->ops->tiocmset) { | ||
3374 | unsigned int set, clear, val; | ||
3375 | |||
3376 | retval = get_user(val, p); | ||
3377 | if (retval) | ||
3378 | return retval; | ||
3379 | |||
3380 | set = clear = 0; | ||
3381 | switch (cmd) { | ||
3382 | case TIOCMBIS: | ||
3383 | set = val; | ||
3384 | break; | ||
3385 | case TIOCMBIC: | ||
3386 | clear = val; | ||
3387 | break; | ||
3388 | case TIOCMSET: | ||
3389 | set = val; | ||
3390 | clear = ~val; | ||
3391 | break; | ||
3392 | } | ||
3393 | 3522 | ||
3394 | set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; | 3523 | if (tty->ops->tiocmset == NULL) |
3395 | clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; | 3524 | return -EINVAL; |
3396 | 3525 | ||
3397 | retval = tty->ops->tiocmset(tty, file, set, clear); | 3526 | retval = get_user(val, p); |
3527 | if (retval) | ||
3528 | return retval; | ||
3529 | set = clear = 0; | ||
3530 | switch (cmd) { | ||
3531 | case TIOCMBIS: | ||
3532 | set = val; | ||
3533 | break; | ||
3534 | case TIOCMBIC: | ||
3535 | clear = val; | ||
3536 | break; | ||
3537 | case TIOCMSET: | ||
3538 | set = val; | ||
3539 | clear = ~val; | ||
3540 | break; | ||
3398 | } | 3541 | } |
3399 | return retval; | 3542 | set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; |
3543 | clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; | ||
3544 | return tty->ops->tiocmset(tty, file, set, clear); | ||
3400 | } | 3545 | } |
3401 | 3546 | ||
3402 | /* | 3547 | /* |
@@ -3501,7 +3646,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
3501 | case TIOCGSID: | 3646 | case TIOCGSID: |
3502 | return tiocgsid(tty, real_tty, p); | 3647 | return tiocgsid(tty, real_tty, p); |
3503 | case TIOCGETD: | 3648 | case TIOCGETD: |
3504 | return put_user(tty->ldisc.num, (int __user *)p); | 3649 | return put_user(tty->ldisc.ops->num, (int __user *)p); |
3505 | case TIOCSETD: | 3650 | case TIOCSETD: |
3506 | return tiocsetd(tty, p); | 3651 | return tiocsetd(tty, p); |
3507 | #ifdef CONFIG_VT | 3652 | #ifdef CONFIG_VT |
@@ -3554,8 +3699,8 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
3554 | } | 3699 | } |
3555 | ld = tty_ldisc_ref_wait(tty); | 3700 | ld = tty_ldisc_ref_wait(tty); |
3556 | retval = -EINVAL; | 3701 | retval = -EINVAL; |
3557 | if (ld->ioctl) { | 3702 | if (ld->ops->ioctl) { |
3558 | retval = ld->ioctl(tty, file, cmd, arg); | 3703 | retval = ld->ops->ioctl(tty, file, cmd, arg); |
3559 | if (retval == -ENOIOCTLCMD) | 3704 | if (retval == -ENOIOCTLCMD) |
3560 | retval = -EINVAL; | 3705 | retval = -EINVAL; |
3561 | } | 3706 | } |
@@ -3582,8 +3727,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, | |||
3582 | } | 3727 | } |
3583 | 3728 | ||
3584 | ld = tty_ldisc_ref_wait(tty); | 3729 | ld = tty_ldisc_ref_wait(tty); |
3585 | if (ld->compat_ioctl) | 3730 | if (ld->ops->compat_ioctl) |
3586 | retval = ld->compat_ioctl(tty, file, cmd, arg); | 3731 | retval = ld->ops->compat_ioctl(tty, file, cmd, arg); |
3587 | tty_ldisc_deref(ld); | 3732 | tty_ldisc_deref(ld); |
3588 | 3733 | ||
3589 | return retval; | 3734 | return retval; |
@@ -3755,7 +3900,8 @@ static void flush_to_ldisc(struct work_struct *work) | |||
3755 | flag_buf = head->flag_buf_ptr + head->read; | 3900 | flag_buf = head->flag_buf_ptr + head->read; |
3756 | head->read += count; | 3901 | head->read += count; |
3757 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 3902 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
3758 | disc->receive_buf(tty, char_buf, flag_buf, count); | 3903 | disc->ops->receive_buf(tty, char_buf, |
3904 | flag_buf, count); | ||
3759 | spin_lock_irqsave(&tty->buf.lock, flags); | 3905 | spin_lock_irqsave(&tty->buf.lock, flags); |
3760 | } | 3906 | } |
3761 | /* Restore the queue head */ | 3907 | /* Restore the queue head */ |
@@ -3816,9 +3962,12 @@ EXPORT_SYMBOL(tty_flip_buffer_push); | |||
3816 | 3962 | ||
3817 | static void initialize_tty_struct(struct tty_struct *tty) | 3963 | static void initialize_tty_struct(struct tty_struct *tty) |
3818 | { | 3964 | { |
3965 | struct tty_ldisc ld; | ||
3819 | memset(tty, 0, sizeof(struct tty_struct)); | 3966 | memset(tty, 0, sizeof(struct tty_struct)); |
3820 | tty->magic = TTY_MAGIC; | 3967 | tty->magic = TTY_MAGIC; |
3821 | tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); | 3968 | if (tty_ldisc_get(N_TTY, &ld) < 0) |
3969 | panic("n_tty: init_tty"); | ||
3970 | tty_ldisc_assign(tty, &ld); | ||
3822 | tty->session = NULL; | 3971 | tty->session = NULL; |
3823 | tty->pgrp = NULL; | 3972 | tty->pgrp = NULL; |
3824 | tty->overrun_time = jiffies; | 3973 | tty->overrun_time = jiffies; |