Commit a352def21a642133758b868c71bee12ab34ad5c5

Authored by Alan Cox
Committed by Linus Torvalds
1 parent e1e5770bb6

tty: Ldisc revamp

Move the line disciplines towards a conventional ->ops arrangement.  For
the moment the actual 'tty_ldisc' struct in the tty is kept as part of
the tty struct but this can then be changed if it turns out that when it
all settles down we want to refcount ldiscs separately to the tty.

Pull the ldisc code out of /proc and put it with our ldisc code.

Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 32 changed files with 286 additions and 246 deletions Side-by-side Diff

drivers/bluetooth/hci_ldisc.c
... ... @@ -282,8 +282,8 @@
282 282 /* FIXME: why is this needed. Note don't use ldisc_ref here as the
283 283 open path is before the ldisc is referencable */
284 284  
285   - if (tty->ldisc.flush_buffer)
286   - tty->ldisc.flush_buffer(tty);
  285 + if (tty->ldisc.ops->flush_buffer)
  286 + tty->ldisc.ops->flush_buffer(tty);
287 287 tty_driver_flush_buffer(tty);
288 288  
289 289 return 0;
... ... @@ -514,7 +514,7 @@
514 514  
515 515 static int __init hci_uart_init(void)
516 516 {
517   - static struct tty_ldisc hci_uart_ldisc;
  517 + static struct tty_ldisc_ops hci_uart_ldisc;
518 518 int err;
519 519  
520 520 BT_INFO("HCI UART driver ver %s", VERSION);
drivers/char/cyclades.c
... ... @@ -5246,7 +5246,8 @@
5246 5246 HZ, info->idle_stats.recv_bytes,
5247 5247 (cur_jifs - info->idle_stats.recv_idle)/
5248 5248 HZ, info->idle_stats.overruns,
5249   - (long)info->tty->ldisc.num);
  5249 + /* FIXME: double check locking */
  5250 + (long)info->tty->ldisc.ops->num);
5250 5251 else
5251 5252 size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
5252 5253 "%10lu %8lu %9lu %6ld\n",
... ... @@ -2262,8 +2262,8 @@
2262 2262 tty_wait_until_sent(tty, 0);
2263 2263 } else {
2264 2264 /* ldisc lock already held in ioctl */
2265   - if (tty->ldisc.flush_buffer)
2266   - tty->ldisc.flush_buffer(tty);
  2265 + if (tty->ldisc.ops->flush_buffer)
  2266 + tty->ldisc.ops->flush_buffer(tty);
2267 2267 }
2268 2268 unlock_kernel();
2269 2269 /* Fall Thru */
drivers/char/ip2/i2lib.c
... ... @@ -868,11 +868,11 @@
868 868 amountToMove = count;
869 869 }
870 870 // Move the first block
871   - pCh->pTTY->ldisc.receive_buf( pCh->pTTY,
  871 + pCh->pTTY->ldisc.ops->receive_buf( pCh->pTTY,
872 872 &(pCh->Ibuf[stripIndex]), NULL, amountToMove );
873 873 // If we needed to wrap, do the second data move
874 874 if (count > amountToMove) {
875   - pCh->pTTY->ldisc.receive_buf( pCh->pTTY,
  875 + pCh->pTTY->ldisc.ops->receive_buf( pCh->pTTY,
876 876 pCh->Ibuf, NULL, count - amountToMove );
877 877 }
878 878 // Bump and wrap the stripIndex all at once by the amount of data read. This
drivers/char/ip2/ip2main.c
... ... @@ -1289,11 +1289,12 @@
1289 1289 // code duplicated from n_tty (ldisc)
1290 1290 static inline void isig(int sig, struct tty_struct *tty, int flush)
1291 1291 {
  1292 + /* FIXME: This is completely bogus */
1292 1293 if (tty->pgrp)
1293 1294 kill_pgrp(tty->pgrp, sig, 1);
1294 1295 if (flush || !L_NOFLSH(tty)) {
1295   - if ( tty->ldisc.flush_buffer )
1296   - tty->ldisc.flush_buffer(tty);
  1296 + if ( tty->ldisc.ops->flush_buffer )
  1297 + tty->ldisc.ops->flush_buffer(tty);
1297 1298 i2InputFlush( tty->driver_data );
1298 1299 }
1299 1300 }
... ... @@ -1342,7 +1343,7 @@
1342 1343 }
1343 1344 tmp = pCh->pTTY->real_raw;
1344 1345 pCh->pTTY->real_raw = 0;
1345   - pCh->pTTY->ldisc.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
  1346 + pCh->pTTY->ldisc->ops.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
1346 1347 pCh->pTTY->real_raw = tmp;
1347 1348 }
1348 1349 #endif /* NEVER_HAPPENS_AS_SETUP_XXX */
drivers/char/n_hdlc.c
... ... @@ -199,7 +199,7 @@
199 199 #define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data))
200 200 #define n_hdlc2tty(n_hdlc) ((n_hdlc)->tty)
201 201  
202   -static struct tty_ldisc n_hdlc_ldisc = {
  202 +static struct tty_ldisc_ops n_hdlc_ldisc = {
203 203 .owner = THIS_MODULE,
204 204 .magic = TTY_LDISC_MAGIC,
205 205 .name = "hdlc",
... ... @@ -342,8 +342,8 @@
342 342 #endif
343 343  
344 344 /* Flush any pending characters in the driver and discipline. */
345   - if (tty->ldisc.flush_buffer)
346   - tty->ldisc.flush_buffer(tty);
  345 + if (tty->ldisc.ops->flush_buffer)
  346 + tty->ldisc.ops->flush_buffer(tty);
347 347  
348 348 tty_driver_flush_buffer(tty);
349 349  
drivers/char/n_r3964.c
... ... @@ -143,7 +143,7 @@
143 143 static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
144 144 char *fp, int count);
145 145  
146   -static struct tty_ldisc tty_ldisc_N_R3964 = {
  146 +static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
147 147 .owner = THIS_MODULE,
148 148 .magic = TTY_LDISC_MAGIC,
149 149 .name = "R3964",
drivers/char/n_tty.c
... ... @@ -1573,7 +1573,7 @@
1573 1573 return mask;
1574 1574 }
1575 1575  
1576   -struct tty_ldisc tty_ldisc_N_TTY = {
  1576 +struct tty_ldisc_ops tty_ldisc_N_TTY = {
1577 1577 .magic = TTY_LDISC_MAGIC,
1578 1578 .name = "n_tty",
1579 1579 .open = n_tty_open,
drivers/char/pcmcia/synclink_cs.c
... ... @@ -514,8 +514,8 @@
514 514 return;
515 515 ld = tty_ldisc_ref(tty);
516 516 if (ld) {
517   - if (ld->receive_buf)
518   - ld->receive_buf(tty, data, flags, count);
  517 + if (ld->ops->receive_buf)
  518 + ld->ops->receive_buf(tty, data, flags, count);
519 519 tty_ldisc_deref(ld);
520 520 }
521 521 }
... ... @@ -111,7 +111,7 @@
111 111 c = to->receive_room;
112 112 if (c > count)
113 113 c = count;
114   - to->ldisc.receive_buf(to, buf, NULL, c);
  114 + to->ldisc.ops->receive_buf(to, buf, NULL, c);
115 115  
116 116 return c;
117 117 }
118 118  
... ... @@ -149,11 +149,11 @@
149 149 int count;
150 150  
151 151 /* We should get the line discipline lock for "tty->link" */
152   - if (!to || !to->ldisc.chars_in_buffer)
  152 + if (!to || !to->ldisc.ops->chars_in_buffer)
153 153 return 0;
154 154  
155 155 /* The ldisc must report 0 if no characters available to be read */
156   - count = to->ldisc.chars_in_buffer(to);
  156 + count = to->ldisc.ops->chars_in_buffer(to);
157 157  
158 158 if (tty->driver->subtype == PTY_TYPE_SLAVE) return count;
159 159  
... ... @@ -186,8 +186,8 @@
186 186 if (!to)
187 187 return;
188 188  
189   - if (to->ldisc.flush_buffer)
190   - to->ldisc.flush_buffer(to);
  189 + if (to->ldisc.ops->flush_buffer)
  190 + to->ldisc.ops->flush_buffer(to);
191 191  
192 192 if (to->packet) {
193 193 spin_lock_irqsave(&tty->ctrl_lock, flags);
drivers/char/selection.c
... ... @@ -327,7 +327,8 @@
327 327 }
328 328 count = sel_buffer_lth - pasted;
329 329 count = min(count, tty->receive_room);
330   - tty->ldisc.receive_buf(tty, sel_buffer + pasted, NULL, count);
  330 + tty->ldisc.ops->receive_buf(tty, sel_buffer + pasted,
  331 + NULL, count);
331 332 pasted += count;
332 333 }
333 334 remove_wait_queue(&vc->paste_wait, &wait);
drivers/char/synclink.c
... ... @@ -975,8 +975,8 @@
975 975 return;
976 976 ld = tty_ldisc_ref(tty);
977 977 if (ld) {
978   - if (ld->receive_buf)
979   - ld->receive_buf(tty, data, flags, count);
  978 + if (ld->ops->receive_buf)
  979 + ld->ops->receive_buf(tty, data, flags, count);
980 980 tty_ldisc_deref(ld);
981 981 }
982 982 }
drivers/char/synclink_gt.c
... ... @@ -641,8 +641,8 @@
641 641 return;
642 642 ld = tty_ldisc_ref(tty);
643 643 if (ld) {
644   - if (ld->receive_buf)
645   - ld->receive_buf(tty, data, flags, count);
  644 + if (ld->ops->receive_buf)
  645 + ld->ops->receive_buf(tty, data, flags, count);
646 646 tty_ldisc_deref(ld);
647 647 }
648 648 }
drivers/char/synclinkmp.c
... ... @@ -712,8 +712,8 @@
712 712 return;
713 713 ld = tty_ldisc_ref(tty);
714 714 if (ld) {
715   - if (ld->receive_buf)
716   - ld->receive_buf(tty, data, flags, count);
  715 + if (ld->ops->receive_buf)
  716 + ld->ops->receive_buf(tty, data, flags, count);
717 717 tty_ldisc_deref(ld);
718 718 }
719 719 }
drivers/char/tty_io.c
... ... @@ -95,8 +95,9 @@
95 95 #include <linux/wait.h>
96 96 #include <linux/bitops.h>
97 97 #include <linux/delay.h>
  98 +#include <linux/seq_file.h>
98 99  
99   -#include <asm/uaccess.h>
  100 +#include <linux/uaccess.h>
100 101 #include <asm/system.h>
101 102  
102 103 #include <linux/kbd_kern.h>
... ... @@ -682,7 +683,7 @@
682 683 static DEFINE_SPINLOCK(tty_ldisc_lock);
683 684 static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
684 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 689 * tty_register_ldisc - install a line discipline
... ... @@ -697,7 +698,7 @@
697 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 703 unsigned long flags;
703 704 int ret = 0;
... ... @@ -706,10 +707,9 @@
706 707 return -EINVAL;
707 708  
708 709 spin_lock_irqsave(&tty_ldisc_lock, flags);
709   - tty_ldiscs[disc] = *new_ldisc;
710   - tty_ldiscs[disc].num = disc;
711   - tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
712   - tty_ldiscs[disc].refcount = 0;
  710 + tty_ldiscs[disc] = new_ldisc;
  711 + new_ldisc->num = disc;
  712 + new_ldisc->refcount = 0;
713 713 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
714 714  
715 715 return ret;
716 716  
717 717  
718 718  
719 719  
... ... @@ -737,19 +737,56 @@
737 737 return -EINVAL;
738 738  
739 739 spin_lock_irqsave(&tty_ldisc_lock, flags);
740   - if (tty_ldiscs[disc].refcount)
  740 + if (tty_ldiscs[disc]->refcount)
741 741 ret = -EBUSY;
742 742 else
743   - tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
  743 + tty_ldiscs[disc] = NULL;
744 744 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
745 745  
746 746 return ret;
747 747 }
748 748 EXPORT_SYMBOL(tty_unregister_ldisc);
749 749  
  750 +
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 +
  786 +/**
751 787 * tty_ldisc_get - take a reference to an ldisc
752 788 * @disc: ldisc number
  789 + * @ld: tty line discipline structure to use
753 790 *
754 791 * Takes a reference to a line discipline. Deals with refcounts and
755 792 * module locking counts. Returns NULL if the discipline is not available.
756 793  
757 794  
758 795  
... ... @@ -760,32 +797,20 @@
760 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;
766   - struct tty_ldisc *ld;
  802 + int err;
767 803  
768 804 if (disc < N_TTY || disc >= NR_LDISCS)
769   - return NULL;
770   -
771   - spin_lock_irqsave(&tty_ldisc_lock, flags);
772   -
773   - ld = &tty_ldiscs[disc];
774   - /* Check the entry is defined */
775   - if (ld->flags & LDISC_FLAG_DEFINED) {
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;
  805 + return -EINVAL;
  806 + err = tty_ldisc_try_get(disc, ld);
  807 + if (err == -EAGAIN) {
  808 + request_module("tty-ldisc-%d", disc);
  809 + err = tty_ldisc_try_get(disc, ld);
  810 + }
  811 + return err;
785 812 }
786 813  
787   -EXPORT_SYMBOL_GPL(tty_ldisc_get);
788   -
789 814 /**
790 815 * tty_ldisc_put - drop ldisc reference
791 816 * @disc: ldisc number
792 817  
793 818  
794 819  
795 820  
796 821  
... ... @@ -797,23 +822,68 @@
797 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 827 unsigned long flags;
  828 + int disc = ld->num;
804 829  
805 830 BUG_ON(disc < N_TTY || disc >= NR_LDISCS);
806 831  
807 832 spin_lock_irqsave(&tty_ldisc_lock, flags);
808   - ld = &tty_ldiscs[disc];
  833 + ld = tty_ldiscs[disc];
809 834 BUG_ON(ld->refcount == 0);
810 835 ld->refcount--;
811 836 module_put(ld->owner);
812 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 +}
816 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 +};
  886 +
817 887 /**
818 888 * tty_ldisc_assign - set ldisc on a tty
819 889 * @tty: tty to assign
820 890  
... ... @@ -829,8 +899,8 @@
829 899  
830 900 static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
831 901 {
  902 + ld->refcount = 0;
832 903 tty->ldisc = *ld;
833   - tty->ldisc.refcount = 0;
834 904 }
835 905  
836 906 /**
... ... @@ -954,6 +1024,41 @@
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 1062 * tty_set_ldisc - set line discipline
958 1063 * @tty: the terminal to set
959 1064 * @ldisc: the line discipline
960 1065  
961 1066  
962 1067  
963 1068  
964 1069  
... ... @@ -967,37 +1072,27 @@
967 1072  
968 1073 static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
969 1074 {
970   - int retval = 0;
971   - struct tty_ldisc o_ldisc;
972   - char buf[64];
  1075 + int retval;
  1076 + struct tty_ldisc o_ldisc, new_ldisc;
973 1077 int work;
974 1078 unsigned long flags;
975   - struct tty_ldisc *ld;
976 1079 struct tty_struct *o_tty;
977 1080  
978   - if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS))
979   - return -EINVAL;
980   -
981 1081 restart:
  1082 + /* This is a bit ugly for now but means we can break the 'ldisc
  1083 + is part of the tty struct' assumption later */
  1084 + retval = tty_ldisc_get(ldisc, &new_ldisc);
  1085 + if (retval)
  1086 + return retval;
982 1087  
983   - ld = tty_ldisc_get(ldisc);
984   - /* Eduardo Blanco <ejbs@cs.cs.com.uy> */
985   - /* Cyrus Durgin <cider@speakeasy.org> */
986   - if (ld == NULL) {
987   - request_module("tty-ldisc-%d", ldisc);
988   - ld = tty_ldisc_get(ldisc);
989   - }
990   - if (ld == NULL)
991   - return -EINVAL;
992   -
993 1088 /*
994 1089 * Problem: What do we do if this blocks ?
995 1090 */
996 1091  
997 1092 tty_wait_until_sent(tty, 0);
998 1093  
999   - if (tty->ldisc.num == ldisc) {
1000   - tty_ldisc_put(ldisc);
  1094 + if (tty->ldisc.ops->num == ldisc) {
  1095 + tty_ldisc_put(new_ldisc.ops);
1001 1096 return 0;
1002 1097 }
1003 1098  
... ... @@ -1024,7 +1119,7 @@
1024 1119 /* Free the new ldisc we grabbed. Must drop the lock
1025 1120 first. */
1026 1121 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1027   - tty_ldisc_put(ldisc);
  1122 + tty_ldisc_put(o_ldisc.ops);
1028 1123 /*
1029 1124 * There are several reasons we may be busy, including
1030 1125 * random momentary I/O traffic. We must therefore
... ... @@ -1038,7 +1133,7 @@
1038 1133 }
1039 1134 if (o_tty && o_tty->ldisc.refcount) {
1040 1135 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1041   - tty_ldisc_put(ldisc);
  1136 + tty_ldisc_put(o_tty->ldisc.ops);
1042 1137 if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
1043 1138 return -ERESTARTSYS;
1044 1139 goto restart;
1045 1140  
... ... @@ -1049,8 +1144,9 @@
1049 1144 * another ldisc change
1050 1145 */
1051 1146 if (!test_bit(TTY_LDISC, &tty->flags)) {
  1147 + struct tty_ldisc *ld;
1052 1148 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1053   - tty_ldisc_put(ldisc);
  1149 + tty_ldisc_put(new_ldisc.ops);
1054 1150 ld = tty_ldisc_ref_wait(tty);
1055 1151 tty_ldisc_deref(ld);
1056 1152 goto restart;
... ... @@ -1060,7 +1156,7 @@
1060 1156 if (o_tty)
1061 1157 clear_bit(TTY_LDISC, &o_tty->flags);
1062 1158 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1063   -
  1159 +
1064 1160 /*
1065 1161 * From this point on we know nobody has an ldisc
1066 1162 * usage reference, nor can they obtain one until
1067 1163  
1068 1164  
1069 1165  
1070 1166  
1071 1167  
1072 1168  
... ... @@ -1070,45 +1166,30 @@
1070 1166 work = cancel_delayed_work(&tty->buf.work);
1071 1167 /*
1072 1168 * Wait for ->hangup_work and ->buf.work handlers to terminate
  1169 + * MUST NOT hold locks here.
1073 1170 */
1074 1171 flush_scheduled_work();
1075 1172 /* Shutdown the current discipline. */
1076   - if (tty->ldisc.close)
1077   - (tty->ldisc.close)(tty);
  1173 + if (o_ldisc.ops->close)
  1174 + (o_ldisc.ops->close)(tty);
1078 1175  
1079 1176 /* Now set up the new line discipline. */
1080   - tty_ldisc_assign(tty, ld);
  1177 + tty_ldisc_assign(tty, &new_ldisc);
1081 1178 tty_set_termios_ldisc(tty, ldisc);
1082   - if (tty->ldisc.open)
1083   - retval = (tty->ldisc.open)(tty);
  1179 + if (new_ldisc.ops->open)
  1180 + retval = (new_ldisc.ops->open)(tty);
1084 1181 if (retval < 0) {
1085   - tty_ldisc_put(ldisc);
1086   - /* There is an outstanding reference here so this is safe */
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   - }
  1182 + tty_ldisc_put(new_ldisc.ops);
  1183 + tty_ldisc_restore(tty, &o_ldisc);
1103 1184 }
1104 1185 /* At this point we hold a reference to the new ldisc and a
1105 1186 a reference to the old ldisc. If we ended up flipping back
1106 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 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 1195 * Allow ldisc referencing to occur as soon as the driver
... ... @@ -1335,8 +1416,8 @@
1335 1416 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
1336 1417 ld = tty_ldisc_ref(tty);
1337 1418 if (ld) {
1338   - if (ld->write_wakeup)
1339   - ld->write_wakeup(tty);
  1419 + if (ld->ops->write_wakeup)
  1420 + ld->ops->write_wakeup(tty);
1340 1421 tty_ldisc_deref(ld);
1341 1422 }
1342 1423 }
... ... @@ -1357,8 +1438,8 @@
1357 1438 {
1358 1439 struct tty_ldisc *ld = tty_ldisc_ref(tty);
1359 1440 if (ld) {
1360   - if (ld->flush_buffer)
1361   - ld->flush_buffer(tty);
  1441 + if (ld->ops->flush_buffer)
  1442 + ld->ops->flush_buffer(tty);
1362 1443 tty_ldisc_deref(ld);
1363 1444 }
1364 1445 tty_buffer_flush(tty);
... ... @@ -1386,7 +1467,7 @@
1386 1467 * do_tty_hangup - actual handler for hangup events
1387 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 1471 * synchronous but doesn't hold any locks, so we need to make sure we
1391 1472 * have the appropriate locks for what we're doing.
1392 1473 *
1393 1474  
... ... @@ -1449,14 +1530,14 @@
1449 1530 ld = tty_ldisc_ref(tty);
1450 1531 if (ld != NULL) {
1451 1532 /* We may have no line discipline at this point */
1452   - if (ld->flush_buffer)
1453   - ld->flush_buffer(tty);
  1533 + if (ld->ops->flush_buffer)
  1534 + ld->ops->flush_buffer(tty);
1454 1535 tty_driver_flush_buffer(tty);
1455 1536 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
1456   - ld->write_wakeup)
1457   - ld->write_wakeup(tty);
1458   - if (ld->hangup)
1459   - ld->hangup(tty);
  1537 + ld->ops->write_wakeup)
  1538 + ld->ops->write_wakeup(tty);
  1539 + if (ld->ops->hangup)
  1540 + ld->ops->hangup(tty);
1460 1541 }
1461 1542 /*
1462 1543 * FIXME: Once we trust the LDISC code better we can wait here for
... ... @@ -1825,8 +1906,8 @@
1825 1906 /* We want to wait for the line discipline to sort out in this
1826 1907 situation */
1827 1908 ld = tty_ldisc_ref_wait(tty);
1828   - if (ld->read)
1829   - i = (ld->read)(tty, file, buf, count);
  1909 + if (ld->ops->read)
  1910 + i = (ld->ops->read)(tty, file, buf, count);
1830 1911 else
1831 1912 i = -EIO;
1832 1913 tty_ldisc_deref(ld);
1833 1914  
... ... @@ -1978,10 +2059,10 @@
1978 2059 printk(KERN_ERR "tty driver %s lacks a write_room method.\n",
1979 2060 tty->driver->name);
1980 2061 ld = tty_ldisc_ref_wait(tty);
1981   - if (!ld->write)
  2062 + if (!ld->ops->write)
1982 2063 ret = -EIO;
1983 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 2066 tty_ldisc_deref(ld);
1986 2067 return ret;
1987 2068 }
... ... @@ -2076,6 +2157,7 @@
2076 2157 struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc;
2077 2158 struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
2078 2159 int retval = 0;
  2160 + struct tty_ldisc *ld;
2079 2161  
2080 2162 /* check whether we're reopening an existing tty */
2081 2163 if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
2082 2164  
2083 2165  
2084 2166  
... ... @@ -2224,17 +2306,19 @@
2224 2306 * If we fail here just call release_tty to clean up. No need
2225 2307 * to decrement the use counts, as release_tty doesn't care.
2226 2308 */
  2309 +
  2310 + ld = &tty->ldisc;
2227 2311  
2228   - if (tty->ldisc.open) {
2229   - retval = (tty->ldisc.open)(tty);
  2312 + if (ld->ops->open) {
  2313 + retval = (ld->ops->open)(tty);
2230 2314 if (retval)
2231 2315 goto release_mem_out;
2232 2316 }
2233   - if (o_tty && o_tty->ldisc.open) {
2234   - retval = (o_tty->ldisc.open)(o_tty);
  2317 + if (o_tty && o_tty->ldisc.ops->open) {
  2318 + retval = (o_tty->ldisc.ops->open)(o_tty);
2235 2319 if (retval) {
2236   - if (tty->ldisc.close)
2237   - (tty->ldisc.close)(tty);
  2320 + if (ld->ops->close)
  2321 + (ld->ops->close)(tty);
2238 2322 goto release_mem_out;
2239 2323 }
2240 2324 tty_ldisc_enable(o_tty);
... ... @@ -2378,6 +2462,7 @@
2378 2462 static void release_dev(struct file *filp)
2379 2463 {
2380 2464 struct tty_struct *tty, *o_tty;
  2465 + struct tty_ldisc ld;
2381 2466 int pty_master, tty_closing, o_tty_closing, do_sleep;
2382 2467 int devpts;
2383 2468 int idx;
2384 2469  
2385 2470  
2386 2471  
... ... @@ -2611,26 +2696,27 @@
2611 2696 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
2612 2697 /*
2613 2698 * Shutdown the current line discipline, and reset it to N_TTY.
2614   - * N.B. why reset ldisc when we're releasing the memory??
2615 2699 *
2616 2700 * FIXME: this MUST get fixed for the new reflocking
2617 2701 */
2618   - if (tty->ldisc.close)
2619   - (tty->ldisc.close)(tty);
2620   - tty_ldisc_put(tty->ldisc.num);
  2702 + if (tty->ldisc.ops->close)
  2703 + (tty->ldisc.ops->close)(tty);
  2704 + tty_ldisc_put(tty->ldisc.ops);
2621 2705  
2622 2706 /*
2623 2707 * Switch the line discipline back
2624 2708 */
2625   - tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
  2709 + WARN_ON(tty_ldisc_get(N_TTY, &ld));
  2710 + tty_ldisc_assign(tty, &ld);
2626 2711 tty_set_termios_ldisc(tty, N_TTY);
2627 2712 if (o_tty) {
2628 2713 /* FIXME: could o_tty be in setldisc here ? */
2629 2714 clear_bit(TTY_LDISC, &o_tty->flags);
2630   - if (o_tty->ldisc.close)
2631   - (o_tty->ldisc.close)(o_tty);
2632   - tty_ldisc_put(o_tty->ldisc.num);
2633   - tty_ldisc_assign(o_tty, tty_ldisc_get(N_TTY));
  2715 + if (o_tty->ldisc.ops->close)
  2716 + (o_tty->ldisc.ops->close)(o_tty);
  2717 + tty_ldisc_put(o_tty->ldisc.ops);
  2718 + WARN_ON(tty_ldisc_get(N_TTY, &ld));
  2719 + tty_ldisc_assign(o_tty, &ld);
2634 2720 tty_set_termios_ldisc(o_tty, N_TTY);
2635 2721 }
2636 2722 /*
... ... @@ -2899,8 +2985,8 @@
2899 2985 return 0;
2900 2986  
2901 2987 ld = tty_ldisc_ref_wait(tty);
2902   - if (ld->poll)
2903   - ret = (ld->poll)(tty, filp, wait);
  2988 + if (ld->ops->poll)
  2989 + ret = (ld->ops->poll)(tty, filp, wait);
2904 2990 tty_ldisc_deref(ld);
2905 2991 return ret;
2906 2992 }
... ... @@ -2974,7 +3060,7 @@
2974 3060 if (get_user(ch, p))
2975 3061 return -EFAULT;
2976 3062 ld = tty_ldisc_ref_wait(tty);
2977   - ld->receive_buf(tty, &ch, &mbz, 1);
  3063 + ld->ops->receive_buf(tty, &ch, &mbz, 1);
2978 3064 tty_ldisc_deref(ld);
2979 3065 return 0;
2980 3066 }
... ... @@ -3528,7 +3614,7 @@
3528 3614 case TIOCGSID:
3529 3615 return tiocgsid(tty, real_tty, p);
3530 3616 case TIOCGETD:
3531   - return put_user(tty->ldisc.num, (int __user *)p);
  3617 + return put_user(tty->ldisc.ops->num, (int __user *)p);
3532 3618 case TIOCSETD:
3533 3619 return tiocsetd(tty, p);
3534 3620 #ifdef CONFIG_VT
... ... @@ -3581,8 +3667,8 @@
3581 3667 }
3582 3668 ld = tty_ldisc_ref_wait(tty);
3583 3669 retval = -EINVAL;
3584   - if (ld->ioctl) {
3585   - retval = ld->ioctl(tty, file, cmd, arg);
  3670 + if (ld->ops->ioctl) {
  3671 + retval = ld->ops->ioctl(tty, file, cmd, arg);
3586 3672 if (retval == -ENOIOCTLCMD)
3587 3673 retval = -EINVAL;
3588 3674 }
... ... @@ -3609,8 +3695,8 @@
3609 3695 }
3610 3696  
3611 3697 ld = tty_ldisc_ref_wait(tty);
3612   - if (ld->compat_ioctl)
3613   - retval = ld->compat_ioctl(tty, file, cmd, arg);
  3698 + if (ld->ops->compat_ioctl)
  3699 + retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
3614 3700 tty_ldisc_deref(ld);
3615 3701  
3616 3702 return retval;
... ... @@ -3782,7 +3868,8 @@
3782 3868 flag_buf = head->flag_buf_ptr + head->read;
3783 3869 head->read += count;
3784 3870 spin_unlock_irqrestore(&tty->buf.lock, flags);
3785   - disc->receive_buf(tty, char_buf, flag_buf, count);
  3871 + disc->ops->receive_buf(tty, char_buf,
  3872 + flag_buf, count);
3786 3873 spin_lock_irqsave(&tty->buf.lock, flags);
3787 3874 }
3788 3875 /* Restore the queue head */
3789 3876  
... ... @@ -3843,9 +3930,12 @@
3843 3930  
3844 3931 static void initialize_tty_struct(struct tty_struct *tty)
3845 3932 {
  3933 + struct tty_ldisc ld;
3846 3934 memset(tty, 0, sizeof(struct tty_struct));
3847 3935 tty->magic = TTY_MAGIC;
3848   - tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
  3936 + if (tty_ldisc_get(N_TTY, &ld) < 0)
  3937 + panic("n_tty: init_tty");
  3938 + tty_ldisc_assign(tty, &ld);
3849 3939 tty->session = NULL;
3850 3940 tty->pgrp = NULL;
3851 3941 tty->overrun_time = jiffies;
drivers/char/tty_ioctl.c
... ... @@ -491,8 +491,8 @@
491 491  
492 492 ld = tty_ldisc_ref(tty);
493 493 if (ld != NULL) {
494   - if (ld->set_termios)
495   - (ld->set_termios)(tty, &old_termios);
  494 + if (ld->ops->set_termios)
  495 + (ld->ops->set_termios)(tty, &old_termios);
496 496 tty_ldisc_deref(ld);
497 497 }
498 498 mutex_unlock(&tty->termios_mutex);
... ... @@ -552,8 +552,8 @@
552 552 ld = tty_ldisc_ref(tty);
553 553  
554 554 if (ld != NULL) {
555   - if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
556   - ld->flush_buffer(tty);
  555 + if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
  556 + ld->ops->flush_buffer(tty);
557 557 tty_ldisc_deref(ld);
558 558 }
559 559  
560 560  
... ... @@ -959,12 +959,12 @@
959 959 ld = tty_ldisc_ref(tty);
960 960 switch (arg) {
961 961 case TCIFLUSH:
962   - if (ld && ld->flush_buffer)
963   - ld->flush_buffer(tty);
  962 + if (ld && ld->ops->flush_buffer)
  963 + ld->ops->flush_buffer(tty);
964 964 break;
965 965 case TCIOFLUSH:
966   - if (ld && ld->flush_buffer)
967   - ld->flush_buffer(tty);
  966 + if (ld && ld->ops->flush_buffer)
  967 + ld->ops->flush_buffer(tty);
968 968 /* fall through */
969 969 case TCOFLUSH:
970 970 tty_driver_flush_buffer(tty);
drivers/input/serio/serport.c
... ... @@ -216,7 +216,7 @@
216 216 * The line discipline structure.
217 217 */
218 218  
219   -static struct tty_ldisc serport_ldisc = {
  219 +static struct tty_ldisc_ops serport_ldisc = {
220 220 .owner = THIS_MODULE,
221 221 .name = "input",
222 222 .open = serport_ldisc_open,
drivers/isdn/capi/capi.c
... ... @@ -466,7 +466,7 @@
466 466 ld = tty_ldisc_ref(mp->tty);
467 467 if (ld == NULL)
468 468 return -1;
469   - if (ld->receive_buf == NULL) {
  469 + if (ld->ops->receive_buf == NULL) {
470 470 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
471 471 printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n");
472 472 #endif
... ... @@ -501,7 +501,7 @@
501 501 printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
502 502 datahandle, skb->len);
503 503 #endif
504   - ld->receive_buf(mp->tty, skb->data, NULL, skb->len);
  504 + ld->ops->receive_buf(mp->tty, skb->data, NULL, skb->len);
505 505 kfree_skb(skb);
506 506 tty_ldisc_deref(ld);
507 507 return 0;
drivers/isdn/gigaset/ser-gigaset.c
... ... @@ -766,7 +766,7 @@
766 766 cs_put(cs);
767 767 }
768 768  
769   -static struct tty_ldisc gigaset_ldisc = {
  769 +static struct tty_ldisc_ops gigaset_ldisc = {
770 770 .owner = THIS_MODULE,
771 771 .magic = TTY_LDISC_MAGIC,
772 772 .name = "ser_gigaset",
drivers/net/hamradio/6pack.c
... ... @@ -783,7 +783,7 @@
783 783 return err;
784 784 }
785 785  
786   -static struct tty_ldisc sp_ldisc = {
  786 +static struct tty_ldisc_ops sp_ldisc = {
787 787 .owner = THIS_MODULE,
788 788 .magic = TTY_LDISC_MAGIC,
789 789 .name = "6pack",
drivers/net/hamradio/mkiss.c
... ... @@ -969,7 +969,7 @@
969 969 mkiss_put(ax);
970 970 }
971 971  
972   -static struct tty_ldisc ax_ldisc = {
  972 +static struct tty_ldisc_ops ax_ldisc = {
973 973 .owner = THIS_MODULE,
974 974 .magic = TTY_LDISC_MAGIC,
975 975 .name = "mkiss",
drivers/net/irda/irtty-sir.c
... ... @@ -533,7 +533,7 @@
533 533  
534 534 /* ------------------------------------------------------- */
535 535  
536   -static struct tty_ldisc irda_ldisc = {
  536 +static struct tty_ldisc_ops irda_ldisc = {
537 537 .magic = TTY_LDISC_MAGIC,
538 538 .name = "irda",
539 539 .flags = 0,
drivers/net/ppp_async.c
... ... @@ -378,7 +378,7 @@
378 378 }
379 379  
380 380  
381   -static struct tty_ldisc ppp_ldisc = {
  381 +static struct tty_ldisc_ops ppp_ldisc = {
382 382 .owner = THIS_MODULE,
383 383 .magic = TTY_LDISC_MAGIC,
384 384 .name = "ppp",
drivers/net/ppp_synctty.c
... ... @@ -418,7 +418,7 @@
418 418 }
419 419  
420 420  
421   -static struct tty_ldisc ppp_sync_ldisc = {
  421 +static struct tty_ldisc_ops ppp_sync_ldisc = {
422 422 .owner = THIS_MODULE,
423 423 .magic = TTY_LDISC_MAGIC,
424 424 .name = "pppsync",
... ... @@ -1301,7 +1301,7 @@
1301 1301 #endif
1302 1302 /* VSV changes end */
1303 1303  
1304   -static struct tty_ldisc sl_ldisc = {
  1304 +static struct tty_ldisc_ops sl_ldisc = {
1305 1305 .owner = THIS_MODULE,
1306 1306 .magic = TTY_LDISC_MAGIC,
1307 1307 .name = "slip",
drivers/net/wan/pc300_tty.c
... ... @@ -688,9 +688,9 @@
688 688 if (cpc_tty->tty) {
689 689 ld = tty_ldisc_ref(cpc_tty->tty);
690 690 if (ld) {
691   - if (ld->receive_buf) {
  691 + if (ld->ops->receive_buf) {
692 692 CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name);
693   - ld->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size);
  693 + ld->ops->receive_buf(cpc_tty->tty, (char *)(buf->data), &flags, buf->size);
694 694 }
695 695 tty_ldisc_deref(ld);
696 696 }
drivers/net/wan/x25_asy.c
... ... @@ -754,7 +754,7 @@
754 754 dev->flags = IFF_NOARP;
755 755 }
756 756  
757   -static struct tty_ldisc x25_ldisc = {
  757 +static struct tty_ldisc_ops x25_ldisc = {
758 758 .owner = THIS_MODULE,
759 759 .magic = TTY_LDISC_MAGIC,
760 760 .name = "X.25",
... ... @@ -136,54 +136,6 @@
136 136 .release = seq_release,
137 137 };
138 138  
139   -static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
140   -{
141   - return (*pos < NR_LDISCS) ? pos : NULL;
142   -}
143   -
144   -static void * tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
145   -{
146   - (*pos)++;
147   - return (*pos < NR_LDISCS) ? pos : NULL;
148   -}
149   -
150   -static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
151   -{
152   -}
153   -
154   -static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
155   -{
156   - int i = *(loff_t *)v;
157   - struct tty_ldisc *ld;
158   -
159   - ld = tty_ldisc_get(i);
160   - if (ld == NULL)
161   - return 0;
162   - seq_printf(m, "%-10s %2d\n", ld->name ? ld->name : "???", i);
163   - tty_ldisc_put(i);
164   - return 0;
165   -}
166   -
167   -static const struct seq_operations tty_ldiscs_seq_ops = {
168   - .start = tty_ldiscs_seq_start,
169   - .next = tty_ldiscs_seq_next,
170   - .stop = tty_ldiscs_seq_stop,
171   - .show = tty_ldiscs_seq_show,
172   -};
173   -
174   -static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
175   -{
176   - return seq_open(file, &tty_ldiscs_seq_ops);
177   -}
178   -
179   -static const struct file_operations tty_ldiscs_proc_fops = {
180   - .owner = THIS_MODULE,
181   - .open = proc_tty_ldiscs_open,
182   - .read = seq_read,
183   - .llseek = seq_lseek,
184   - .release = seq_release,
185   -};
186   -
187 139 /*
188 140 * This function is called by tty_register_driver() to handle
189 141 * registering the driver's /proc handler into /proc/tty/driver/<foo>
... ... @@ -185,6 +185,7 @@
185 185 struct tty_driver *driver;
186 186 const struct tty_operations *ops;
187 187 int index;
  188 + /* The ldisc objects are protected by tty_ldisc_lock at the moment */
188 189 struct tty_ldisc ldisc;
189 190 struct mutex termios_mutex;
190 191 spinlock_t ctrl_lock;
... ... @@ -289,7 +290,7 @@
289 290 extern int tty_check_change(struct tty_struct * tty);
290 291 extern void stop_tty(struct tty_struct * tty);
291 292 extern void start_tty(struct tty_struct * tty);
292   -extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc);
  293 +extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
293 294 extern int tty_unregister_ldisc(int disc);
294 295 extern int tty_register_driver(struct tty_driver *driver);
295 296 extern int tty_unregister_driver(struct tty_driver *driver);
296 297  
... ... @@ -330,10 +331,8 @@
330 331 extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *);
331 332 extern void tty_ldisc_deref(struct tty_ldisc *);
332 333 extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *);
  334 +extern const struct file_operations tty_ldiscs_proc_fops;
333 335  
334   -extern struct tty_ldisc *tty_ldisc_get(int);
335   -extern void tty_ldisc_put(int);
336   -
337 336 extern void tty_wakeup(struct tty_struct *tty);
338 337 extern void tty_ldisc_flush(struct tty_struct *tty);
339 338  
... ... @@ -354,7 +353,7 @@
354 353  
355 354  
356 355 /* n_tty.c */
357   -extern struct tty_ldisc tty_ldisc_N_TTY;
  356 +extern struct tty_ldisc_ops tty_ldisc_N_TTY;
358 357  
359 358 /* tty_audit.c */
360 359 #ifdef CONFIG_AUDIT
include/linux/tty_ldisc.h
... ... @@ -104,7 +104,7 @@
104 104 #include <linux/fs.h>
105 105 #include <linux/wait.h>
106 106  
107   -struct tty_ldisc {
  107 +struct tty_ldisc_ops {
108 108 int magic;
109 109 char *name;
110 110 int num;
... ... @@ -139,6 +139,11 @@
139 139  
140 140 struct module *owner;
141 141  
  142 + int refcount;
  143 +};
  144 +
  145 +struct tty_ldisc {
  146 + struct tty_ldisc_ops *ops;
142 147 int refcount;
143 148 };
144 149  
net/bluetooth/rfcomm/tty.c
... ... @@ -617,14 +617,7 @@
617 617 return;
618 618  
619 619 BT_DBG("dev %p tty %p", dev, tty);
620   -
621   - if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
622   - (tty->ldisc.write_wakeup)(tty);
623   -
624   - wake_up_interruptible(&tty->write_wait);
625   -#ifdef SERIAL_HAVE_POLL_WAIT
626   - wake_up_interruptible(&tty->poll_wait);
627   -#endif
  620 + tty_wakeup(tty);
628 621 }
629 622  
630 623 static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
... ... @@ -1005,9 +998,7 @@
1005 998 return;
1006 999  
1007 1000 skb_queue_purge(&dev->dlc->tx_queue);
1008   -
1009   - if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
1010   - tty->ldisc.write_wakeup(tty);
  1001 + tty_wakeup(tty);
1011 1002 }
1012 1003  
1013 1004 static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
net/irda/ircomm/ircomm_tty.c
... ... @@ -650,12 +650,7 @@
650 650 }
651 651  
652 652 /* Check if user (still) wants to be waken up */
653   - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
654   - tty->ldisc.write_wakeup)
655   - {
656   - (tty->ldisc.write_wakeup)(tty);
657   - }
658   - wake_up_interruptible(&tty->write_wait);
  653 + tty_wakeup(tty);
659 654 }
660 655  
661 656 /*
... ... @@ -1141,6 +1136,7 @@
1141 1136 struct sk_buff *skb)
1142 1137 {
1143 1138 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
  1139 + struct tty_ldisc *ld;
1144 1140  
1145 1141 IRDA_DEBUG(2, "%s()\n", __func__ );
1146 1142  
... ... @@ -1173,7 +1169,11 @@
1173 1169 * involve the flip buffers, since we are not running in an interrupt
1174 1170 * handler
1175 1171 */
1176   - self->tty->ldisc.receive_buf(self->tty, skb->data, NULL, skb->len);
  1172 +
  1173 + ld = tty_ldisc_ref(self->tty);
  1174 + if (ld)
  1175 + ld->ops->receive_buf(self->tty, skb->data, NULL, skb->len);
  1176 + tty_ldisc_deref(ld);
1177 1177  
1178 1178 /* No need to kfree_skb - see ircomm_ttp_data_indication() */
1179 1179