aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/bluetooth/hci_ldisc.c6
-rw-r--r--drivers/char/cyclades.c3
-rw-r--r--drivers/char/epca.c4
-rw-r--r--drivers/char/ip2/i2lib.c4
-rw-r--r--drivers/char/ip2/ip2main.c7
-rw-r--r--drivers/char/n_hdlc.c6
-rw-r--r--drivers/char/n_r3964.c2
-rw-r--r--drivers/char/n_tty.c2
-rw-r--r--drivers/char/pcmcia/synclink_cs.c4
-rw-r--r--drivers/char/pty.c10
-rw-r--r--drivers/char/selection.c3
-rw-r--r--drivers/char/synclink.c4
-rw-r--r--drivers/char/synclink_gt.c4
-rw-r--r--drivers/char/synclinkmp.c4
-rw-r--r--drivers/char/tty_io.c336
-rw-r--r--drivers/char/tty_ioctl.c16
-rw-r--r--drivers/input/serio/serport.c2
-rw-r--r--drivers/isdn/capi/capi.c4
-rw-r--r--drivers/isdn/gigaset/ser-gigaset.c2
-rw-r--r--drivers/net/hamradio/6pack.c2
-rw-r--r--drivers/net/hamradio/mkiss.c2
-rw-r--r--drivers/net/irda/irtty-sir.c2
-rw-r--r--drivers/net/ppp_async.c2
-rw-r--r--drivers/net/ppp_synctty.c2
-rw-r--r--drivers/net/slip.c2
-rw-r--r--drivers/net/wan/pc300_tty.c4
-rw-r--r--drivers/net/wan/x25_asy.c2
-rw-r--r--fs/proc/proc_tty.c48
-rw-r--r--include/linux/tty.h9
-rw-r--r--include/linux/tty_ldisc.h7
-rw-r--r--net/bluetooth/rfcomm/tty.c13
-rw-r--r--net/irda/ircomm/ircomm_tty.c14
32 files changed, 286 insertions, 246 deletions
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index e5cd856a2fea..69df187d74ce 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -282,8 +282,8 @@ static int hci_uart_tty_open(struct tty_struct *tty)
282 /* FIXME: why is this needed. Note don't use ldisc_ref here as the 282 /* FIXME: why is this needed. Note don't use ldisc_ref here as the
283 open path is before the ldisc is referencable */ 283 open path is before the ldisc is referencable */
284 284
285 if (tty->ldisc.flush_buffer) 285 if (tty->ldisc.ops->flush_buffer)
286 tty->ldisc.flush_buffer(tty); 286 tty->ldisc.ops->flush_buffer(tty);
287 tty_driver_flush_buffer(tty); 287 tty_driver_flush_buffer(tty);
288 288
289 return 0; 289 return 0;
@@ -514,7 +514,7 @@ static unsigned int hci_uart_tty_poll(struct tty_struct *tty,
514 514
515static int __init hci_uart_init(void) 515static 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 int err; 518 int err;
519 519
520 BT_INFO("HCI UART driver ver %s", VERSION); 520 BT_INFO("HCI UART driver ver %s", VERSION);
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 6bff9d87dc57..a957dbcc5a46 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -5246,7 +5246,8 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
5246 HZ, info->idle_stats.recv_bytes, 5246 HZ, info->idle_stats.recv_bytes,
5247 (cur_jifs - info->idle_stats.recv_idle)/ 5247 (cur_jifs - info->idle_stats.recv_idle)/
5248 HZ, info->idle_stats.overruns, 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 else 5251 else
5251 size = sprintf(buf + len, "%3d %8lu %10lu %8lu " 5252 size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
5252 "%10lu %8lu %9lu %6ld\n", 5253 "%10lu %8lu %9lu %6ld\n",
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 60a4df7dac12..aa8e19f44b45 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -2262,8 +2262,8 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file,
2262 tty_wait_until_sent(tty, 0); 2262 tty_wait_until_sent(tty, 0);
2263 } else { 2263 } else {
2264 /* ldisc lock already held in ioctl */ 2264 /* ldisc lock already held in ioctl */
2265 if (tty->ldisc.flush_buffer) 2265 if (tty->ldisc.ops->flush_buffer)
2266 tty->ldisc.flush_buffer(tty); 2266 tty->ldisc.ops->flush_buffer(tty);
2267 } 2267 }
2268 unlock_kernel(); 2268 unlock_kernel();
2269 /* Fall Thru */ 2269 /* Fall Thru */
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
index 938879cc7bcc..0061e18aff60 100644
--- a/drivers/char/ip2/i2lib.c
+++ b/drivers/char/ip2/i2lib.c
@@ -868,11 +868,11 @@ i2Input(i2ChanStrPtr pCh)
868 amountToMove = count; 868 amountToMove = count;
869 } 869 }
870 // Move the first block 870 // Move the first block
871 pCh->pTTY->ldisc.receive_buf( pCh->pTTY, 871 pCh->pTTY->ldisc.ops->receive_buf( pCh->pTTY,
872 &(pCh->Ibuf[stripIndex]), NULL, amountToMove ); 872 &(pCh->Ibuf[stripIndex]), NULL, amountToMove );
873 // If we needed to wrap, do the second data move 873 // If we needed to wrap, do the second data move
874 if (count > amountToMove) { 874 if (count > amountToMove) {
875 pCh->pTTY->ldisc.receive_buf( pCh->pTTY, 875 pCh->pTTY->ldisc.ops->receive_buf( pCh->pTTY,
876 pCh->Ibuf, NULL, count - amountToMove ); 876 pCh->Ibuf, NULL, count - amountToMove );
877 } 877 }
878 // Bump and wrap the stripIndex all at once by the amount of data read. This 878 // Bump and wrap the stripIndex all at once by the amount of data read. This
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 9a2394cda943..5dc74404058f 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -1289,11 +1289,12 @@ static void do_input(struct work_struct *work)
1289// code duplicated from n_tty (ldisc) 1289// code duplicated from n_tty (ldisc)
1290static inline void isig(int sig, struct tty_struct *tty, int flush) 1290static inline void isig(int sig, struct tty_struct *tty, int flush)
1291{ 1291{
1292 /* FIXME: This is completely bogus */
1292 if (tty->pgrp) 1293 if (tty->pgrp)
1293 kill_pgrp(tty->pgrp, sig, 1); 1294 kill_pgrp(tty->pgrp, sig, 1);
1294 if (flush || !L_NOFLSH(tty)) { 1295 if (flush || !L_NOFLSH(tty)) {
1295 if ( tty->ldisc.flush_buffer ) 1296 if ( tty->ldisc.ops->flush_buffer )
1296 tty->ldisc.flush_buffer(tty); 1297 tty->ldisc.ops->flush_buffer(tty);
1297 i2InputFlush( tty->driver_data ); 1298 i2InputFlush( tty->driver_data );
1298 } 1299 }
1299} 1300}
@@ -1342,7 +1343,7 @@ static void do_status(struct work_struct *work)
1342 } 1343 }
1343 tmp = pCh->pTTY->real_raw; 1344 tmp = pCh->pTTY->real_raw;
1344 pCh->pTTY->real_raw = 0; 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 pCh->pTTY->real_raw = tmp; 1347 pCh->pTTY->real_raw = tmp;
1347 } 1348 }
1348#endif /* NEVER_HAPPENS_AS_SETUP_XXX */ 1349#endif /* NEVER_HAPPENS_AS_SETUP_XXX */
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index a35bfd7ee80e..ed4e03333ab4 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -199,7 +199,7 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty);
199#define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data)) 199#define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data))
200#define n_hdlc2tty(n_hdlc) ((n_hdlc)->tty) 200#define n_hdlc2tty(n_hdlc) ((n_hdlc)->tty)
201 201
202static struct tty_ldisc n_hdlc_ldisc = { 202static struct tty_ldisc_ops n_hdlc_ldisc = {
203 .owner = THIS_MODULE, 203 .owner = THIS_MODULE,
204 .magic = TTY_LDISC_MAGIC, 204 .magic = TTY_LDISC_MAGIC,
205 .name = "hdlc", 205 .name = "hdlc",
@@ -342,8 +342,8 @@ static int n_hdlc_tty_open (struct tty_struct *tty)
342#endif 342#endif
343 343
344 /* Flush any pending characters in the driver and discipline. */ 344 /* Flush any pending characters in the driver and discipline. */
345 if (tty->ldisc.flush_buffer) 345 if (tty->ldisc.ops->flush_buffer)
346 tty->ldisc.flush_buffer(tty); 346 tty->ldisc.ops->flush_buffer(tty);
347 347
348 tty_driver_flush_buffer(tty); 348 tty_driver_flush_buffer(tty);
349 349
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 902169062332..ae377aa473ba 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -143,7 +143,7 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
143static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, 143static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
144 char *fp, int count); 144 char *fp, int count);
145 145
146static struct tty_ldisc tty_ldisc_N_R3964 = { 146static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
147 .owner = THIS_MODULE, 147 .owner = THIS_MODULE,
148 .magic = TTY_LDISC_MAGIC, 148 .magic = TTY_LDISC_MAGIC,
149 .name = "R3964", 149 .name = "R3964",
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 8096389b0dc2..708c2b1dbe51 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -1573,7 +1573,7 @@ static unsigned int normal_poll(struct tty_struct *tty, struct file *file,
1573 return mask; 1573 return mask;
1574} 1574}
1575 1575
1576struct tty_ldisc tty_ldisc_N_TTY = { 1576struct tty_ldisc_ops tty_ldisc_N_TTY = {
1577 .magic = TTY_LDISC_MAGIC, 1577 .magic = TTY_LDISC_MAGIC,
1578 .name = "n_tty", 1578 .name = "n_tty",
1579 .open = n_tty_open, 1579 .open = n_tty_open,
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 1dd0e992c83d..95743e2682fe 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -514,8 +514,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
514 return; 514 return;
515 ld = tty_ldisc_ref(tty); 515 ld = tty_ldisc_ref(tty);
516 if (ld) { 516 if (ld) {
517 if (ld->receive_buf) 517 if (ld->ops->receive_buf)
518 ld->receive_buf(tty, data, flags, count); 518 ld->ops->receive_buf(tty, data, flags, count);
519 tty_ldisc_deref(ld); 519 tty_ldisc_deref(ld);
520 } 520 }
521} 521}
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 0a05c038ae6f..76b27932d229 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -111,7 +111,7 @@ static int pty_write(struct tty_struct * tty, const unsigned char *buf, int coun
111 c = to->receive_room; 111 c = to->receive_room;
112 if (c > count) 112 if (c > count)
113 c = count; 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 return c; 116 return c;
117} 117}
@@ -149,11 +149,11 @@ static int pty_chars_in_buffer(struct tty_struct *tty)
149 int count; 149 int count;
150 150
151 /* We should get the line discipline lock for "tty->link" */ 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 return 0; 153 return 0;
154 154
155 /* The ldisc must report 0 if no characters available to be read */ 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 if (tty->driver->subtype == PTY_TYPE_SLAVE) return count; 158 if (tty->driver->subtype == PTY_TYPE_SLAVE) return count;
159 159
@@ -186,8 +186,8 @@ static void pty_flush_buffer(struct tty_struct *tty)
186 if (!to) 186 if (!to)
187 return; 187 return;
188 188
189 if (to->ldisc.flush_buffer) 189 if (to->ldisc.ops->flush_buffer)
190 to->ldisc.flush_buffer(to); 190 to->ldisc.ops->flush_buffer(to);
191 191
192 if (to->packet) { 192 if (to->packet) {
193 spin_lock_irqsave(&tty->ctrl_lock, flags); 193 spin_lock_irqsave(&tty->ctrl_lock, flags);
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index d63f5ccc29e6..2978a49a172b 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -327,7 +327,8 @@ int paste_selection(struct tty_struct *tty)
327 } 327 }
328 count = sel_buffer_lth - pasted; 328 count = sel_buffer_lth - pasted;
329 count = min(count, tty->receive_room); 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 pasted += count; 332 pasted += count;
332 } 333 }
333 remove_wait_queue(&vc->paste_wait, &wait); 334 remove_wait_queue(&vc->paste_wait, &wait);
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index ac5080df2565..5e4b2e638d0c 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -975,8 +975,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
975 return; 975 return;
976 ld = tty_ldisc_ref(tty); 976 ld = tty_ldisc_ref(tty);
977 if (ld) { 977 if (ld) {
978 if (ld->receive_buf) 978 if (ld->ops->receive_buf)
979 ld->receive_buf(tty, data, flags, count); 979 ld->ops->receive_buf(tty, data, flags, count);
980 tty_ldisc_deref(ld); 980 tty_ldisc_deref(ld);
981 } 981 }
982} 982}
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 55c1653be00c..e473778cd6fa 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -641,8 +641,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
641 return; 641 return;
642 ld = tty_ldisc_ref(tty); 642 ld = tty_ldisc_ref(tty);
643 if (ld) { 643 if (ld) {
644 if (ld->receive_buf) 644 if (ld->ops->receive_buf)
645 ld->receive_buf(tty, data, flags, count); 645 ld->ops->receive_buf(tty, data, flags, count);
646 tty_ldisc_deref(ld); 646 tty_ldisc_deref(ld);
647 } 647 }
648} 648}
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index bec54866e0bb..5341b5aaf8bc 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -712,8 +712,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
712 return; 712 return;
713 ld = tty_ldisc_ref(tty); 713 ld = tty_ldisc_ref(tty);
714 if (ld) { 714 if (ld) {
715 if (ld->receive_buf) 715 if (ld->ops->receive_buf)
716 ld->receive_buf(tty, data, flags, count); 716 ld->ops->receive_buf(tty, data, flags, count);
717 tty_ldisc_deref(ld); 717 tty_ldisc_deref(ld);
718 } 718 }
719} 719}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 047a17339f83..54c4ada460ee 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)
682static DEFINE_SPINLOCK(tty_ldisc_lock); 683static DEFINE_SPINLOCK(tty_ldisc_lock);
683static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); 684static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
684/* Line disc dispatch table */ 685/* Line disc dispatch table */
685static struct tty_ldisc tty_ldiscs[NR_LDISCS]; 686static 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
700int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) 701int 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}
748EXPORT_SYMBOL(tty_unregister_ldisc); 748EXPORT_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
761static 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
763struct tty_ldisc *tty_ldisc_get(int disc) 800static 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
787EXPORT_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
800void tty_ldisc_put(int disc) 825static 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
815EXPORT_SYMBOL_GPL(tty_ldisc_put); 840static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
841{
842 return (*pos < NR_LDISCS) ? pos : NULL;
843}
844
845static 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
851static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
852{
853}
854
855static 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
867static 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
874static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
875{
876 return seq_open(file, &tty_ldiscs_seq_ops);
877}
878
879const 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
830static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) 900static 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
1035static 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
968static int tty_set_ldisc(struct tty_struct *tty, int ldisc) 1073static 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
981restart: 1081restart:
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 1470k * 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}
@@ -2076,6 +2157,7 @@ static int init_dev(struct tty_driver *driver, int idx,
2076 struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; 2157 struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc;
2077 struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; 2158 struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
2078 int retval = 0; 2159 int retval = 0;
2160 struct tty_ldisc *ld;
2079 2161
2080 /* check whether we're reopening an existing tty */ 2162 /* check whether we're reopening an existing tty */
2081 if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { 2163 if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
@@ -2224,17 +2306,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 2306 * 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. 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) { 2312 if (ld->ops->open) {
2229 retval = (tty->ldisc.open)(tty); 2313 retval = (ld->ops->open)(tty);
2230 if (retval) 2314 if (retval)
2231 goto release_mem_out; 2315 goto release_mem_out;
2232 } 2316 }
2233 if (o_tty && o_tty->ldisc.open) { 2317 if (o_tty && o_tty->ldisc.ops->open) {
2234 retval = (o_tty->ldisc.open)(o_tty); 2318 retval = (o_tty->ldisc.ops->open)(o_tty);
2235 if (retval) { 2319 if (retval) {
2236 if (tty->ldisc.close) 2320 if (ld->ops->close)
2237 (tty->ldisc.close)(tty); 2321 (ld->ops->close)(tty);
2238 goto release_mem_out; 2322 goto release_mem_out;
2239 } 2323 }
2240 tty_ldisc_enable(o_tty); 2324 tty_ldisc_enable(o_tty);
@@ -2378,6 +2462,7 @@ static void release_tty(struct tty_struct *tty, int idx)
2378static void release_dev(struct file *filp) 2462static void release_dev(struct file *filp)
2379{ 2463{
2380 struct tty_struct *tty, *o_tty; 2464 struct tty_struct *tty, *o_tty;
2465 struct tty_ldisc ld;
2381 int pty_master, tty_closing, o_tty_closing, do_sleep; 2466 int pty_master, tty_closing, o_tty_closing, do_sleep;
2382 int devpts; 2467 int devpts;
2383 int idx; 2468 int idx;
@@ -2611,26 +2696,27 @@ static void release_dev(struct file *filp)
2611 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 2696 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
2612 /* 2697 /*
2613 * Shutdown the current line discipline, and reset it to N_TTY. 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 * FIXME: this MUST get fixed for the new reflocking 2700 * FIXME: this MUST get fixed for the new reflocking
2617 */ 2701 */
2618 if (tty->ldisc.close) 2702 if (tty->ldisc.ops->close)
2619 (tty->ldisc.close)(tty); 2703 (tty->ldisc.ops->close)(tty);
2620 tty_ldisc_put(tty->ldisc.num); 2704 tty_ldisc_put(tty->ldisc.ops);
2621 2705
2622 /* 2706 /*
2623 * Switch the line discipline back 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 tty_set_termios_ldisc(tty, N_TTY); 2711 tty_set_termios_ldisc(tty, N_TTY);
2627 if (o_tty) { 2712 if (o_tty) {
2628 /* FIXME: could o_tty be in setldisc here ? */ 2713 /* FIXME: could o_tty be in setldisc here ? */
2629 clear_bit(TTY_LDISC, &o_tty->flags); 2714 clear_bit(TTY_LDISC, &o_tty->flags);
2630 if (o_tty->ldisc.close) 2715 if (o_tty->ldisc.ops->close)
2631 (o_tty->ldisc.close)(o_tty); 2716 (o_tty->ldisc.ops->close)(o_tty);
2632 tty_ldisc_put(o_tty->ldisc.num); 2717 tty_ldisc_put(o_tty->ldisc.ops);
2633 tty_ldisc_assign(o_tty, tty_ldisc_get(N_TTY)); 2718 WARN_ON(tty_ldisc_get(N_TTY, &ld));
2719 tty_ldisc_assign(o_tty, &ld);
2634 tty_set_termios_ldisc(o_tty, N_TTY); 2720 tty_set_termios_ldisc(o_tty, N_TTY);
2635 } 2721 }
2636 /* 2722 /*
@@ -2899,8 +2985,8 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait)
2899 return 0; 2985 return 0;
2900 2986
2901 ld = tty_ldisc_ref_wait(tty); 2987 ld = tty_ldisc_ref_wait(tty);
2902 if (ld->poll) 2988 if (ld->ops->poll)
2903 ret = (ld->poll)(tty, filp, wait); 2989 ret = (ld->ops->poll)(tty, filp, wait);
2904 tty_ldisc_deref(ld); 2990 tty_ldisc_deref(ld);
2905 return ret; 2991 return ret;
2906} 2992}
@@ -2974,7 +3060,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
2974 if (get_user(ch, p)) 3060 if (get_user(ch, p))
2975 return -EFAULT; 3061 return -EFAULT;
2976 ld = tty_ldisc_ref_wait(tty); 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 tty_ldisc_deref(ld); 3064 tty_ldisc_deref(ld);
2979 return 0; 3065 return 0;
2980} 3066}
@@ -3528,7 +3614,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3528 case TIOCGSID: 3614 case TIOCGSID:
3529 return tiocgsid(tty, real_tty, p); 3615 return tiocgsid(tty, real_tty, p);
3530 case TIOCGETD: 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 case TIOCSETD: 3618 case TIOCSETD:
3533 return tiocsetd(tty, p); 3619 return tiocsetd(tty, p);
3534#ifdef CONFIG_VT 3620#ifdef CONFIG_VT
@@ -3581,8 +3667,8 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3581 } 3667 }
3582 ld = tty_ldisc_ref_wait(tty); 3668 ld = tty_ldisc_ref_wait(tty);
3583 retval = -EINVAL; 3669 retval = -EINVAL;
3584 if (ld->ioctl) { 3670 if (ld->ops->ioctl) {
3585 retval = ld->ioctl(tty, file, cmd, arg); 3671 retval = ld->ops->ioctl(tty, file, cmd, arg);
3586 if (retval == -ENOIOCTLCMD) 3672 if (retval == -ENOIOCTLCMD)
3587 retval = -EINVAL; 3673 retval = -EINVAL;
3588 } 3674 }
@@ -3609,8 +3695,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
3609 } 3695 }
3610 3696
3611 ld = tty_ldisc_ref_wait(tty); 3697 ld = tty_ldisc_ref_wait(tty);
3612 if (ld->compat_ioctl) 3698 if (ld->ops->compat_ioctl)
3613 retval = ld->compat_ioctl(tty, file, cmd, arg); 3699 retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
3614 tty_ldisc_deref(ld); 3700 tty_ldisc_deref(ld);
3615 3701
3616 return retval; 3702 return retval;
@@ -3782,7 +3868,8 @@ static void flush_to_ldisc(struct work_struct *work)
3782 flag_buf = head->flag_buf_ptr + head->read; 3868 flag_buf = head->flag_buf_ptr + head->read;
3783 head->read += count; 3869 head->read += count;
3784 spin_unlock_irqrestore(&tty->buf.lock, flags); 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 spin_lock_irqsave(&tty->buf.lock, flags); 3873 spin_lock_irqsave(&tty->buf.lock, flags);
3787 } 3874 }
3788 /* Restore the queue head */ 3875 /* Restore the queue head */
@@ -3843,9 +3930,12 @@ EXPORT_SYMBOL(tty_flip_buffer_push);
3843 3930
3844static void initialize_tty_struct(struct tty_struct *tty) 3931static void initialize_tty_struct(struct tty_struct *tty)
3845{ 3932{
3933 struct tty_ldisc ld;
3846 memset(tty, 0, sizeof(struct tty_struct)); 3934 memset(tty, 0, sizeof(struct tty_struct));
3847 tty->magic = TTY_MAGIC; 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 tty->session = NULL; 3939 tty->session = NULL;
3850 tty->pgrp = NULL; 3940 tty->pgrp = NULL;
3851 tty->overrun_time = jiffies; 3941 tty->overrun_time = jiffies;
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 8f81139d6194..ea9fc5d03b99 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -491,8 +491,8 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
491 491
492 ld = tty_ldisc_ref(tty); 492 ld = tty_ldisc_ref(tty);
493 if (ld != NULL) { 493 if (ld != NULL) {
494 if (ld->set_termios) 494 if (ld->ops->set_termios)
495 (ld->set_termios)(tty, &old_termios); 495 (ld->ops->set_termios)(tty, &old_termios);
496 tty_ldisc_deref(ld); 496 tty_ldisc_deref(ld);
497 } 497 }
498 mutex_unlock(&tty->termios_mutex); 498 mutex_unlock(&tty->termios_mutex);
@@ -552,8 +552,8 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
552 ld = tty_ldisc_ref(tty); 552 ld = tty_ldisc_ref(tty);
553 553
554 if (ld != NULL) { 554 if (ld != NULL) {
555 if ((opt & TERMIOS_FLUSH) && ld->flush_buffer) 555 if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
556 ld->flush_buffer(tty); 556 ld->ops->flush_buffer(tty);
557 tty_ldisc_deref(ld); 557 tty_ldisc_deref(ld);
558 } 558 }
559 559
@@ -959,12 +959,12 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
959 ld = tty_ldisc_ref(tty); 959 ld = tty_ldisc_ref(tty);
960 switch (arg) { 960 switch (arg) {
961 case TCIFLUSH: 961 case TCIFLUSH:
962 if (ld && ld->flush_buffer) 962 if (ld && ld->ops->flush_buffer)
963 ld->flush_buffer(tty); 963 ld->ops->flush_buffer(tty);
964 break; 964 break;
965 case TCIOFLUSH: 965 case TCIOFLUSH:
966 if (ld && ld->flush_buffer) 966 if (ld && ld->ops->flush_buffer)
967 ld->flush_buffer(tty); 967 ld->ops->flush_buffer(tty);
968 /* fall through */ 968 /* fall through */
969 case TCOFLUSH: 969 case TCOFLUSH:
970 tty_driver_flush_buffer(tty); 970 tty_driver_flush_buffer(tty);
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index 7ff71ba7b7c9..b9694b6445d0 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -216,7 +216,7 @@ static void serport_ldisc_write_wakeup(struct tty_struct * tty)
216 * The line discipline structure. 216 * The line discipline structure.
217 */ 217 */
218 218
219static struct tty_ldisc serport_ldisc = { 219static struct tty_ldisc_ops serport_ldisc = {
220 .owner = THIS_MODULE, 220 .owner = THIS_MODULE,
221 .name = "input", 221 .name = "input",
222 .open = serport_ldisc_open, 222 .open = serport_ldisc_open,
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 2095153582f1..8a35029caca0 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -466,7 +466,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
466 ld = tty_ldisc_ref(mp->tty); 466 ld = tty_ldisc_ref(mp->tty);
467 if (ld == NULL) 467 if (ld == NULL)
468 return -1; 468 return -1;
469 if (ld->receive_buf == NULL) { 469 if (ld->ops->receive_buf == NULL) {
470#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) 470#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
471 printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n"); 471 printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n");
472#endif 472#endif
@@ -501,7 +501,7 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
501 printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n", 501 printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
502 datahandle, skb->len); 502 datahandle, skb->len);
503#endif 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 kfree_skb(skb); 505 kfree_skb(skb);
506 tty_ldisc_deref(ld); 506 tty_ldisc_deref(ld);
507 return 0; 507 return 0;
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index 45d1ee93cd39..5e89fa177816 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -766,7 +766,7 @@ gigaset_tty_wakeup(struct tty_struct *tty)
766 cs_put(cs); 766 cs_put(cs);
767} 767}
768 768
769static struct tty_ldisc gigaset_ldisc = { 769static struct tty_ldisc_ops gigaset_ldisc = {
770 .owner = THIS_MODULE, 770 .owner = THIS_MODULE,
771 .magic = TTY_LDISC_MAGIC, 771 .magic = TTY_LDISC_MAGIC,
772 .name = "ser_gigaset", 772 .name = "ser_gigaset",
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 9d5721287d6f..19dd0a61749c 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -783,7 +783,7 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
783 return err; 783 return err;
784} 784}
785 785
786static struct tty_ldisc sp_ldisc = { 786static struct tty_ldisc_ops sp_ldisc = {
787 .owner = THIS_MODULE, 787 .owner = THIS_MODULE,
788 .magic = TTY_LDISC_MAGIC, 788 .magic = TTY_LDISC_MAGIC,
789 .name = "6pack", 789 .name = "6pack",
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 65166035aca0..c6ca47599fd4 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -969,7 +969,7 @@ out:
969 mkiss_put(ax); 969 mkiss_put(ax);
970} 970}
971 971
972static struct tty_ldisc ax_ldisc = { 972static struct tty_ldisc_ops ax_ldisc = {
973 .owner = THIS_MODULE, 973 .owner = THIS_MODULE,
974 .magic = TTY_LDISC_MAGIC, 974 .magic = TTY_LDISC_MAGIC,
975 .name = "mkiss", 975 .name = "mkiss",
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index e6f40b7f9041..9e33196f9459 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -533,7 +533,7 @@ static void irtty_close(struct tty_struct *tty)
533 533
534/* ------------------------------------------------------- */ 534/* ------------------------------------------------------- */
535 535
536static struct tty_ldisc irda_ldisc = { 536static struct tty_ldisc_ops irda_ldisc = {
537 .magic = TTY_LDISC_MAGIC, 537 .magic = TTY_LDISC_MAGIC,
538 .name = "irda", 538 .name = "irda",
539 .flags = 0, 539 .flags = 0,
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index f1a52def1241..451bdb57d6fc 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -378,7 +378,7 @@ ppp_asynctty_wakeup(struct tty_struct *tty)
378} 378}
379 379
380 380
381static struct tty_ldisc ppp_ldisc = { 381static struct tty_ldisc_ops ppp_ldisc = {
382 .owner = THIS_MODULE, 382 .owner = THIS_MODULE,
383 .magic = TTY_LDISC_MAGIC, 383 .magic = TTY_LDISC_MAGIC,
384 .name = "ppp", 384 .name = "ppp",
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index b8f0369a71e7..801d8f99d471 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -418,7 +418,7 @@ ppp_sync_wakeup(struct tty_struct *tty)
418} 418}
419 419
420 420
421static struct tty_ldisc ppp_sync_ldisc = { 421static struct tty_ldisc_ops ppp_sync_ldisc = {
422 .owner = THIS_MODULE, 422 .owner = THIS_MODULE,
423 .magic = TTY_LDISC_MAGIC, 423 .magic = TTY_LDISC_MAGIC,
424 .name = "pppsync", 424 .name = "pppsync",
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 84af68fdb6c2..1d58991d395b 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -1301,7 +1301,7 @@ static int sl_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1301#endif 1301#endif
1302/* VSV changes end */ 1302/* VSV changes end */
1303 1303
1304static struct tty_ldisc sl_ldisc = { 1304static struct tty_ldisc_ops sl_ldisc = {
1305 .owner = THIS_MODULE, 1305 .owner = THIS_MODULE,
1306 .magic = TTY_LDISC_MAGIC, 1306 .magic = TTY_LDISC_MAGIC,
1307 .name = "slip", 1307 .name = "slip",
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
index e03eef2f2282..c2c10c632260 100644
--- a/drivers/net/wan/pc300_tty.c
+++ b/drivers/net/wan/pc300_tty.c
@@ -688,9 +688,9 @@ static void cpc_tty_rx_work(struct work_struct *work)
688 if (cpc_tty->tty) { 688 if (cpc_tty->tty) {
689 ld = tty_ldisc_ref(cpc_tty->tty); 689 ld = tty_ldisc_ref(cpc_tty->tty);
690 if (ld) { 690 if (ld) {
691 if (ld->receive_buf) { 691 if (ld->ops->receive_buf) {
692 CPC_TTY_DBG("%s: call line disc. receive_buf\n",cpc_tty->name); 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 tty_ldisc_deref(ld); 695 tty_ldisc_deref(ld);
696 } 696 }
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 069f8bb0a99f..2a6c7a60756f 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -754,7 +754,7 @@ static void x25_asy_setup(struct net_device *dev)
754 dev->flags = IFF_NOARP; 754 dev->flags = IFF_NOARP;
755} 755}
756 756
757static struct tty_ldisc x25_ldisc = { 757static struct tty_ldisc_ops x25_ldisc = {
758 .owner = THIS_MODULE, 758 .owner = THIS_MODULE,
759 .magic = TTY_LDISC_MAGIC, 759 .magic = TTY_LDISC_MAGIC,
760 .name = "X.25", 760 .name = "X.25",
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c
index 21f490f5d65c..d153946d6d15 100644
--- a/fs/proc/proc_tty.c
+++ b/fs/proc/proc_tty.c
@@ -136,54 +136,6 @@ static const struct file_operations proc_tty_drivers_operations = {
136 .release = seq_release, 136 .release = seq_release,
137}; 137};
138 138
139static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
140{
141 return (*pos < NR_LDISCS) ? pos : NULL;
142}
143
144static 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
150static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
151{
152}
153
154static 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
167static 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
174static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
175{
176 return seq_open(file, &tty_ldiscs_seq_ops);
177}
178
179static 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 * This function is called by tty_register_driver() to handle 140 * This function is called by tty_register_driver() to handle
189 * registering the driver's /proc handler into /proc/tty/driver/<foo> 141 * registering the driver's /proc handler into /proc/tty/driver/<foo>
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 324a3b231d40..013711ea7385 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -185,6 +185,7 @@ struct tty_struct {
185 struct tty_driver *driver; 185 struct tty_driver *driver;
186 const struct tty_operations *ops; 186 const struct tty_operations *ops;
187 int index; 187 int index;
188 /* The ldisc objects are protected by tty_ldisc_lock at the moment */
188 struct tty_ldisc ldisc; 189 struct tty_ldisc ldisc;
189 struct mutex termios_mutex; 190 struct mutex termios_mutex;
190 spinlock_t ctrl_lock; 191 spinlock_t ctrl_lock;
@@ -289,7 +290,7 @@ extern void tty_wait_until_sent(struct tty_struct * tty, long timeout);
289extern int tty_check_change(struct tty_struct * tty); 290extern int tty_check_change(struct tty_struct * tty);
290extern void stop_tty(struct tty_struct * tty); 291extern void stop_tty(struct tty_struct * tty);
291extern void start_tty(struct tty_struct * tty); 292extern void start_tty(struct tty_struct * tty);
292extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc); 293extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc);
293extern int tty_unregister_ldisc(int disc); 294extern int tty_unregister_ldisc(int disc);
294extern int tty_register_driver(struct tty_driver *driver); 295extern int tty_register_driver(struct tty_driver *driver);
295extern int tty_unregister_driver(struct tty_driver *driver); 296extern int tty_unregister_driver(struct tty_driver *driver);
@@ -330,9 +331,7 @@ extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b);
330extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); 331extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *);
331extern void tty_ldisc_deref(struct tty_ldisc *); 332extern void tty_ldisc_deref(struct tty_ldisc *);
332extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *); 333extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *);
333 334extern const struct file_operations tty_ldiscs_proc_fops;
334extern struct tty_ldisc *tty_ldisc_get(int);
335extern void tty_ldisc_put(int);
336 335
337extern void tty_wakeup(struct tty_struct *tty); 336extern void tty_wakeup(struct tty_struct *tty);
338extern void tty_ldisc_flush(struct tty_struct *tty); 337extern void tty_ldisc_flush(struct tty_struct *tty);
@@ -354,7 +353,7 @@ extern int tty_write_lock(struct tty_struct *tty, int ndelay);
354 353
355 354
356/* n_tty.c */ 355/* n_tty.c */
357extern struct tty_ldisc tty_ldisc_N_TTY; 356extern struct tty_ldisc_ops tty_ldisc_N_TTY;
358 357
359/* tty_audit.c */ 358/* tty_audit.c */
360#ifdef CONFIG_AUDIT 359#ifdef CONFIG_AUDIT
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
index 6226504d9108..40f38d896777 100644
--- a/include/linux/tty_ldisc.h
+++ b/include/linux/tty_ldisc.h
@@ -104,7 +104,7 @@
104#include <linux/fs.h> 104#include <linux/fs.h>
105#include <linux/wait.h> 105#include <linux/wait.h>
106 106
107struct tty_ldisc { 107struct tty_ldisc_ops {
108 int magic; 108 int magic;
109 char *name; 109 char *name;
110 int num; 110 int num;
@@ -142,6 +142,11 @@ struct tty_ldisc {
142 int refcount; 142 int refcount;
143}; 143};
144 144
145struct tty_ldisc {
146 struct tty_ldisc_ops *ops;
147 int refcount;
148};
149
145#define TTY_LDISC_MAGIC 0x5403 150#define TTY_LDISC_MAGIC 0x5403
146 151
147#define LDISC_FLAG_DEFINED 0x00000001 152#define LDISC_FLAG_DEFINED 0x00000001
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index c9191871c1e0..0a387f2eb7a9 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -617,14 +617,7 @@ static void rfcomm_tty_wakeup(unsigned long arg)
617 return; 617 return;
618 618
619 BT_DBG("dev %p tty %p", dev, tty); 619 BT_DBG("dev %p tty %p", dev, tty);
620 620 tty_wakeup(tty);
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
628} 621}
629 622
630static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) 623static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
@@ -1005,9 +998,7 @@ static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
1005 return; 998 return;
1006 999
1007 skb_queue_purge(&dev->dlc->tx_queue); 1000 skb_queue_purge(&dev->dlc->tx_queue);
1008 1001 tty_wakeup(tty);
1009 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
1010 tty->ldisc.write_wakeup(tty);
1011} 1002}
1012 1003
1013static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch) 1004static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 76c3057d0179..e4e2caeb9d82 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -650,12 +650,7 @@ static void ircomm_tty_do_softint(struct work_struct *work)
650 } 650 }
651 651
652 /* Check if user (still) wants to be waken up */ 652 /* Check if user (still) wants to be waken up */
653 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && 653 tty_wakeup(tty);
654 tty->ldisc.write_wakeup)
655 {
656 (tty->ldisc.write_wakeup)(tty);
657 }
658 wake_up_interruptible(&tty->write_wait);
659} 654}
660 655
661/* 656/*
@@ -1141,6 +1136,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
1141 struct sk_buff *skb) 1136 struct sk_buff *skb)
1142{ 1137{
1143 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance; 1138 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
1139 struct tty_ldisc *ld;
1144 1140
1145 IRDA_DEBUG(2, "%s()\n", __func__ ); 1141 IRDA_DEBUG(2, "%s()\n", __func__ );
1146 1142
@@ -1173,7 +1169,11 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
1173 * involve the flip buffers, since we are not running in an interrupt 1169 * involve the flip buffers, since we are not running in an interrupt
1174 * handler 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 /* No need to kfree_skb - see ircomm_ttp_data_indication() */ 1178 /* No need to kfree_skb - see ircomm_ttp_data_indication() */
1179 1179