aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2009-06-11 07:50:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-11 11:51:01 -0400
commitc65c9bc3efa5589f691276bb9db689119a711222 (patch)
treeccb86ffb28ecafa77623fb2789faae8e4c1e2c4b
parente8b70e7d3e86319a8b2aaabde3866833d92cd80f (diff)
tty: rewrite the ldisc locking
There are several pretty much unfixable races in the old ldisc code, especially with respect to pty behaviour and also to hangup. It's easier to rewrite the code than simply try and patch it up. This patch - splits the ldisc from the tty (so we will be able to refcount it more cleanly later) - introduces a mutex lock for ldisc changing on an active device - fixes the complete mess that hangup caused - implements hopefully correct setldisc/close/hangup locking There are still some problems around pty pairs that have always been there but at least it is now possible to understand the code and fix further problems. This fixes the following known bugs - hang up can leak ldisc references - hang up may not call open/close on ldisc in a matched way - pty/tty pairs can deadlock during an ldisc change - reading the ldisc proc files can cause every ldisc to be loaded and probably a few other of the mysterious ldisc race reports. I'm sure it also adds the odd new one. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/bluetooth/hci_ldisc.c4
-rw-r--r--drivers/char/cyclades.c2
-rw-r--r--drivers/char/epca.c4
-rw-r--r--drivers/char/ip2/i2lib.c4
-rw-r--r--drivers/char/ip2/ip2main.c4
-rw-r--r--drivers/char/n_hdlc.c4
-rw-r--r--drivers/char/pty.c10
-rw-r--r--drivers/char/selection.c2
-rw-r--r--drivers/char/tty_io.c64
-rw-r--r--drivers/char/tty_ldisc.c477
-rw-r--r--include/linux/tty.h9
11 files changed, 330 insertions, 254 deletions
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index af761dc434f6..688015128594 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -277,8 +277,8 @@ static int hci_uart_tty_open(struct tty_struct *tty)
277 /* FIXME: why is this needed. Note don't use ldisc_ref here as the 277 /* FIXME: why is this needed. Note don't use ldisc_ref here as the
278 open path is before the ldisc is referencable */ 278 open path is before the ldisc is referencable */
279 279
280 if (tty->ldisc.ops->flush_buffer) 280 if (tty->ldisc->ops->flush_buffer)
281 tty->ldisc.ops->flush_buffer(tty); 281 tty->ldisc->ops->flush_buffer(tty);
282 tty_driver_flush_buffer(tty); 282 tty_driver_flush_buffer(tty);
283 283
284 return 0; 284 return 0;
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 456019051742..f3366d3f06cf 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -5200,7 +5200,7 @@ static int cyclades_proc_show(struct seq_file *m, void *v)
5200 (cur_jifs - info->idle_stats.recv_idle)/ 5200 (cur_jifs - info->idle_stats.recv_idle)/
5201 HZ, info->idle_stats.overruns, 5201 HZ, info->idle_stats.overruns,
5202 /* FIXME: double check locking */ 5202 /* FIXME: double check locking */
5203 (long)info->port.tty->ldisc.ops->num); 5203 (long)info->port.tty->ldisc->ops->num);
5204 else 5204 else
5205 seq_printf(m, "%3d %8lu %10lu %8lu " 5205 seq_printf(m, "%3d %8lu %10lu %8lu "
5206 "%10lu %8lu %9lu %6ld\n", 5206 "%10lu %8lu %9lu %6ld\n",
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 710ee9333057..abef1f7d84fe 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -2114,8 +2114,8 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file,
2114 tty_wait_until_sent(tty, 0); 2114 tty_wait_until_sent(tty, 0);
2115 } else { 2115 } else {
2116 /* ldisc lock already held in ioctl */ 2116 /* ldisc lock already held in ioctl */
2117 if (tty->ldisc.ops->flush_buffer) 2117 if (tty->ldisc->ops->flush_buffer)
2118 tty->ldisc.ops->flush_buffer(tty); 2118 tty->ldisc->ops->flush_buffer(tty);
2119 } 2119 }
2120 unlock_kernel(); 2120 unlock_kernel();
2121 /* Fall Thru */ 2121 /* Fall Thru */
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
index 0061e18aff60..0d10b89218ed 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.ops->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.ops->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 afd9247cf082..517271c762e6 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -1315,8 +1315,8 @@ static inline void isig(int sig, struct tty_struct *tty, int flush)
1315 if (tty->pgrp) 1315 if (tty->pgrp)
1316 kill_pgrp(tty->pgrp, sig, 1); 1316 kill_pgrp(tty->pgrp, sig, 1);
1317 if (flush || !L_NOFLSH(tty)) { 1317 if (flush || !L_NOFLSH(tty)) {
1318 if ( tty->ldisc.ops->flush_buffer ) 1318 if ( tty->ldisc->ops->flush_buffer )
1319 tty->ldisc.ops->flush_buffer(tty); 1319 tty->ldisc->ops->flush_buffer(tty);
1320 i2InputFlush( tty->driver_data ); 1320 i2InputFlush( tty->driver_data );
1321 } 1321 }
1322} 1322}
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index bacb3e2872ae..461ece591a5b 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -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.ops->flush_buffer) 345 if (tty->ldisc->ops->flush_buffer)
346 tty->ldisc.ops->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/pty.c b/drivers/char/pty.c
index da2cb8c70c11..5acd29e6e043 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -110,7 +110,7 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf,
110 c = to->receive_room; 110 c = to->receive_room;
111 if (c > count) 111 if (c > count)
112 c = count; 112 c = count;
113 to->ldisc.ops->receive_buf(to, buf, NULL, c); 113 to->ldisc->ops->receive_buf(to, buf, NULL, c);
114 114
115 return c; 115 return c;
116} 116}
@@ -148,11 +148,11 @@ static int pty_chars_in_buffer(struct tty_struct *tty)
148 int count; 148 int count;
149 149
150 /* We should get the line discipline lock for "tty->link" */ 150 /* We should get the line discipline lock for "tty->link" */
151 if (!to || !to->ldisc.ops->chars_in_buffer) 151 if (!to || !to->ldisc->ops->chars_in_buffer)
152 return 0; 152 return 0;
153 153
154 /* The ldisc must report 0 if no characters available to be read */ 154 /* The ldisc must report 0 if no characters available to be read */
155 count = to->ldisc.ops->chars_in_buffer(to); 155 count = to->ldisc->ops->chars_in_buffer(to);
156 156
157 if (tty->driver->subtype == PTY_TYPE_SLAVE) 157 if (tty->driver->subtype == PTY_TYPE_SLAVE)
158 return count; 158 return count;
@@ -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.ops->flush_buffer) 189 if (to->ldisc->ops->flush_buffer)
190 to->ldisc.ops->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 cb8ca5698963..f97b9e848064 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -327,7 +327,7 @@ 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.ops->receive_buf(tty, sel_buffer + pasted, 330 tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
331 NULL, count); 331 NULL, count);
332 pasted += count; 332 pasted += count;
333 } 333 }
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index be49d0730bb9..2f44b0b241c3 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -492,22 +492,6 @@ void tty_ldisc_flush(struct tty_struct *tty)
492EXPORT_SYMBOL_GPL(tty_ldisc_flush); 492EXPORT_SYMBOL_GPL(tty_ldisc_flush);
493 493
494/** 494/**
495 * tty_reset_termios - reset terminal state
496 * @tty: tty to reset
497 *
498 * Restore a terminal to the driver default state
499 */
500
501static void tty_reset_termios(struct tty_struct *tty)
502{
503 mutex_lock(&tty->termios_mutex);
504 *tty->termios = tty->driver->init_termios;
505 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
506 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
507 mutex_unlock(&tty->termios_mutex);
508}
509
510/**
511 * do_tty_hangup - actual handler for hangup events 495 * do_tty_hangup - actual handler for hangup events
512 * @work: tty device 496 * @work: tty device
513 * 497 *
@@ -536,7 +520,6 @@ static void do_tty_hangup(struct work_struct *work)
536 struct file *cons_filp = NULL; 520 struct file *cons_filp = NULL;
537 struct file *filp, *f = NULL; 521 struct file *filp, *f = NULL;
538 struct task_struct *p; 522 struct task_struct *p;
539 struct tty_ldisc *ld;
540 int closecount = 0, n; 523 int closecount = 0, n;
541 unsigned long flags; 524 unsigned long flags;
542 int refs = 0; 525 int refs = 0;
@@ -567,40 +550,8 @@ static void do_tty_hangup(struct work_struct *work)
567 filp->f_op = &hung_up_tty_fops; 550 filp->f_op = &hung_up_tty_fops;
568 } 551 }
569 file_list_unlock(); 552 file_list_unlock();
570 /*
571 * FIXME! What are the locking issues here? This may me overdoing
572 * things... This question is especially important now that we've
573 * removed the irqlock.
574 */
575 ld = tty_ldisc_ref(tty);
576 if (ld != NULL) {
577 /* We may have no line discipline at this point */
578 if (ld->ops->flush_buffer)
579 ld->ops->flush_buffer(tty);
580 tty_driver_flush_buffer(tty);
581 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
582 ld->ops->write_wakeup)
583 ld->ops->write_wakeup(tty);
584 if (ld->ops->hangup)
585 ld->ops->hangup(tty);
586 }
587 /*
588 * FIXME: Once we trust the LDISC code better we can wait here for
589 * ldisc completion and fix the driver call race
590 */
591 wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
592 wake_up_interruptible_poll(&tty->read_wait, POLLIN);
593 /*
594 * Shutdown the current line discipline, and reset it to
595 * N_TTY.
596 */
597 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
598 tty_reset_termios(tty);
599 /* Defer ldisc switch */
600 /* tty_deferred_ldisc_switch(N_TTY);
601 553
602 This should get done automatically when the port closes and 554 tty_ldisc_hangup(tty);
603 tty_release is called */
604 555
605 read_lock(&tasklist_lock); 556 read_lock(&tasklist_lock);
606 if (tty->session) { 557 if (tty->session) {
@@ -629,12 +580,15 @@ static void do_tty_hangup(struct work_struct *work)
629 read_unlock(&tasklist_lock); 580 read_unlock(&tasklist_lock);
630 581
631 spin_lock_irqsave(&tty->ctrl_lock, flags); 582 spin_lock_irqsave(&tty->ctrl_lock, flags);
632 tty->flags = 0; 583 clear_bit(TTY_THROTTLED, &tty->flags);
584 clear_bit(TTY_PUSH, &tty->flags);
585 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
633 put_pid(tty->session); 586 put_pid(tty->session);
634 put_pid(tty->pgrp); 587 put_pid(tty->pgrp);
635 tty->session = NULL; 588 tty->session = NULL;
636 tty->pgrp = NULL; 589 tty->pgrp = NULL;
637 tty->ctrl_status = 0; 590 tty->ctrl_status = 0;
591 set_bit(TTY_HUPPED, &tty->flags);
638 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 592 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
639 593
640 /* Account for the p->signal references we killed */ 594 /* Account for the p->signal references we killed */
@@ -660,10 +614,7 @@ static void do_tty_hangup(struct work_struct *work)
660 * can't yet guarantee all that. 614 * can't yet guarantee all that.
661 */ 615 */
662 set_bit(TTY_HUPPED, &tty->flags); 616 set_bit(TTY_HUPPED, &tty->flags);
663 if (ld) { 617 tty_ldisc_enable(tty);
664 tty_ldisc_enable(tty);
665 tty_ldisc_deref(ld);
666 }
667 unlock_kernel(); 618 unlock_kernel();
668 if (f) 619 if (f)
669 fput(f); 620 fput(f);
@@ -2570,7 +2521,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2570 case TIOCGSID: 2521 case TIOCGSID:
2571 return tiocgsid(tty, real_tty, p); 2522 return tiocgsid(tty, real_tty, p);
2572 case TIOCGETD: 2523 case TIOCGETD:
2573 return put_user(tty->ldisc.ops->num, (int __user *)p); 2524 return put_user(tty->ldisc->ops->num, (int __user *)p);
2574 case TIOCSETD: 2525 case TIOCSETD:
2575 return tiocsetd(tty, p); 2526 return tiocsetd(tty, p);
2576 /* 2527 /*
@@ -2785,6 +2736,7 @@ void initialize_tty_struct(struct tty_struct *tty,
2785 tty->buf.head = tty->buf.tail = NULL; 2736 tty->buf.head = tty->buf.tail = NULL;
2786 tty_buffer_init(tty); 2737 tty_buffer_init(tty);
2787 mutex_init(&tty->termios_mutex); 2738 mutex_init(&tty->termios_mutex);
2739 mutex_init(&tty->ldisc_mutex);
2788 init_waitqueue_head(&tty->write_wait); 2740 init_waitqueue_head(&tty->write_wait);
2789 init_waitqueue_head(&tty->read_wait); 2741 init_waitqueue_head(&tty->read_wait);
2790 INIT_WORK(&tty->hangup_work, do_tty_hangup); 2742 INIT_WORK(&tty->hangup_work, do_tty_hangup);
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index e3c6416aa86d..a58a19a6a5e1 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -115,19 +115,22 @@ EXPORT_SYMBOL(tty_unregister_ldisc);
115/** 115/**
116 * tty_ldisc_try_get - try and reference an ldisc 116 * tty_ldisc_try_get - try and reference an ldisc
117 * @disc: ldisc number 117 * @disc: ldisc number
118 * @ld: tty ldisc structure to complete
119 * 118 *
120 * Attempt to open and lock a line discipline into place. Return 119 * Attempt to open and lock a line discipline into place. Return
121 * the line discipline refcounted and assigned in ld. On an error 120 * the line discipline refcounted or an error.
122 * report the error code back
123 */ 121 */
124 122
125static int tty_ldisc_try_get(int disc, struct tty_ldisc *ld) 123static struct tty_ldisc *tty_ldisc_try_get(int disc)
126{ 124{
127 unsigned long flags; 125 unsigned long flags;
126 struct tty_ldisc *ld;
128 struct tty_ldisc_ops *ldops; 127 struct tty_ldisc_ops *ldops;
129 int err = -EINVAL; 128 int err = -EINVAL;
130 129
130 ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
131 if (ld == NULL)
132 return ERR_PTR(-ENOMEM);
133
131 spin_lock_irqsave(&tty_ldisc_lock, flags); 134 spin_lock_irqsave(&tty_ldisc_lock, flags);
132 ld->ops = NULL; 135 ld->ops = NULL;
133 ldops = tty_ldiscs[disc]; 136 ldops = tty_ldiscs[disc];
@@ -140,17 +143,19 @@ static int tty_ldisc_try_get(int disc, struct tty_ldisc *ld)
140 /* lock it */ 143 /* lock it */
141 ldops->refcount++; 144 ldops->refcount++;
142 ld->ops = ldops; 145 ld->ops = ldops;
146 ld->refcount = 0;
143 err = 0; 147 err = 0;
144 } 148 }
145 } 149 }
146 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 150 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
147 return err; 151 if (err)
152 return ERR_PTR(err);
153 return ld;
148} 154}
149 155
150/** 156/**
151 * tty_ldisc_get - take a reference to an ldisc 157 * tty_ldisc_get - take a reference to an ldisc
152 * @disc: ldisc number 158 * @disc: ldisc number
153 * @ld: tty line discipline structure to use
154 * 159 *
155 * Takes a reference to a line discipline. Deals with refcounts and 160 * Takes a reference to a line discipline. Deals with refcounts and
156 * module locking counts. Returns NULL if the discipline is not available. 161 * module locking counts. Returns NULL if the discipline is not available.
@@ -161,44 +166,46 @@ static int tty_ldisc_try_get(int disc, struct tty_ldisc *ld)
161 * takes tty_ldisc_lock to guard against ldisc races 166 * takes tty_ldisc_lock to guard against ldisc races
162 */ 167 */
163 168
164static int tty_ldisc_get(int disc, struct tty_ldisc *ld) 169static struct tty_ldisc *tty_ldisc_get(int disc)
165{ 170{
166 int err; 171 struct tty_ldisc *ld;
167 172
168 if (disc < N_TTY || disc >= NR_LDISCS) 173 if (disc < N_TTY || disc >= NR_LDISCS)
169 return -EINVAL; 174 return ERR_PTR(-EINVAL);
170 err = tty_ldisc_try_get(disc, ld); 175 ld = tty_ldisc_try_get(disc);
171 if (err < 0) { 176 if (IS_ERR(ld)) {
172 request_module("tty-ldisc-%d", disc); 177 request_module("tty-ldisc-%d", disc);
173 err = tty_ldisc_try_get(disc, ld); 178 ld = tty_ldisc_try_get(disc);
174 } 179 }
175 return err; 180 return ld;
176} 181}
177 182
178/** 183/**
179 * tty_ldisc_put - drop ldisc reference 184 * tty_ldisc_put - drop ldisc reference
180 * @disc: ldisc number 185 * @ld: ldisc
181 * 186 *
182 * Drop a reference to a line discipline. Manage refcounts and 187 * Drop a reference to a line discipline. Manage refcounts and
183 * module usage counts 188 * module usage counts. Free the ldisc once the recount hits zero.
184 * 189 *
185 * Locking: 190 * Locking:
186 * takes tty_ldisc_lock to guard against ldisc races 191 * takes tty_ldisc_lock to guard against ldisc races
187 */ 192 */
188 193
189static void tty_ldisc_put(struct tty_ldisc_ops *ld) 194static void tty_ldisc_put(struct tty_ldisc *ld)
190{ 195{
191 unsigned long flags; 196 unsigned long flags;
192 int disc = ld->num; 197 int disc = ld->ops->num;
198 struct tty_ldisc_ops *ldo;
193 199
194 BUG_ON(disc < N_TTY || disc >= NR_LDISCS); 200 BUG_ON(disc < N_TTY || disc >= NR_LDISCS);
195 201
196 spin_lock_irqsave(&tty_ldisc_lock, flags); 202 spin_lock_irqsave(&tty_ldisc_lock, flags);
197 ld = tty_ldiscs[disc]; 203 ldo = tty_ldiscs[disc];
198 BUG_ON(ld->refcount == 0); 204 BUG_ON(ldo->refcount == 0);
199 ld->refcount--; 205 ldo->refcount--;
200 module_put(ld->owner); 206 module_put(ldo->owner);
201 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 207 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
208 kfree(ld);
202} 209}
203 210
204static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos) 211static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
@@ -219,12 +226,13 @@ static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
219static int tty_ldiscs_seq_show(struct seq_file *m, void *v) 226static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
220{ 227{
221 int i = *(loff_t *)v; 228 int i = *(loff_t *)v;
222 struct tty_ldisc ld; 229 struct tty_ldisc *ld;
223 230
224 if (tty_ldisc_get(i, &ld) < 0) 231 ld = tty_ldisc_try_get(i);
232 if (IS_ERR(ld))
225 return 0; 233 return 0;
226 seq_printf(m, "%-10s %2d\n", ld.ops->name ? ld.ops->name : "???", i); 234 seq_printf(m, "%-10s %2d\n", ld->ops->name ? ld->ops->name : "???", i);
227 tty_ldisc_put(ld.ops); 235 tty_ldisc_put(ld);
228 return 0; 236 return 0;
229} 237}
230 238
@@ -263,8 +271,7 @@ const struct file_operations tty_ldiscs_proc_fops = {
263 271
264static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) 272static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
265{ 273{
266 ld->refcount = 0; 274 tty->ldisc = ld;
267 tty->ldisc = *ld;
268} 275}
269 276
270/** 277/**
@@ -286,7 +293,7 @@ static int tty_ldisc_try(struct tty_struct *tty)
286 int ret = 0; 293 int ret = 0;
287 294
288 spin_lock_irqsave(&tty_ldisc_lock, flags); 295 spin_lock_irqsave(&tty_ldisc_lock, flags);
289 ld = &tty->ldisc; 296 ld = tty->ldisc;
290 if (test_bit(TTY_LDISC, &tty->flags)) { 297 if (test_bit(TTY_LDISC, &tty->flags)) {
291 ld->refcount++; 298 ld->refcount++;
292 ret = 1; 299 ret = 1;
@@ -315,8 +322,8 @@ struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
315{ 322{
316 /* wait_event is a macro */ 323 /* wait_event is a macro */
317 wait_event(tty_ldisc_wait, tty_ldisc_try(tty)); 324 wait_event(tty_ldisc_wait, tty_ldisc_try(tty));
318 WARN_ON(tty->ldisc.refcount == 0); 325 WARN_ON(tty->ldisc->refcount == 0);
319 return &tty->ldisc; 326 return tty->ldisc;
320} 327}
321 328
322EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait); 329EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
@@ -335,7 +342,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
335struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty) 342struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
336{ 343{
337 if (tty_ldisc_try(tty)) 344 if (tty_ldisc_try(tty))
338 return &tty->ldisc; 345 return tty->ldisc;
339 return NULL; 346 return NULL;
340} 347}
341 348
@@ -407,6 +414,39 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
407 mutex_unlock(&tty->termios_mutex); 414 mutex_unlock(&tty->termios_mutex);
408} 415}
409 416
417/**
418 * tty_ldisc_open - open a line discipline
419 * @tty: tty we are opening the ldisc on
420 * @ld: discipline to open
421 *
422 * A helper opening method. Also a convenient debugging and check
423 * point.
424 */
425
426static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
427{
428 WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
429 if (ld->ops->open)
430 return ld->ops->open(tty);
431 return 0;
432}
433
434/**
435 * tty_ldisc_close - close a line discipline
436 * @tty: tty we are opening the ldisc on
437 * @ld: discipline to close
438 *
439 * A helper close method. Also a convenient debugging and check
440 * point.
441 */
442
443static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
444{
445 WARN_ON(!test_bit(TTY_LDISC_OPEN, &tty->flags));
446 clear_bit(TTY_LDISC_OPEN, &tty->flags);
447 if (ld->ops->close)
448 ld->ops->close(tty);
449}
410 450
411/** 451/**
412 * tty_ldisc_restore - helper for tty ldisc change 452 * tty_ldisc_restore - helper for tty ldisc change
@@ -420,31 +460,32 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
420static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) 460static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
421{ 461{
422 char buf[64]; 462 char buf[64];
423 struct tty_ldisc new_ldisc; 463 struct tty_ldisc *new_ldisc;
464 int r;
424 465
425 /* There is an outstanding reference here so this is safe */ 466 /* There is an outstanding reference here so this is safe */
426 tty_ldisc_get(old->ops->num, old); 467 old = tty_ldisc_get(old->ops->num);
468 WARN_ON(IS_ERR(old));
427 tty_ldisc_assign(tty, old); 469 tty_ldisc_assign(tty, old);
428 tty_set_termios_ldisc(tty, old->ops->num); 470 tty_set_termios_ldisc(tty, old->ops->num);
429 if (old->ops->open && (old->ops->open(tty) < 0)) { 471 if (tty_ldisc_open(tty, old) < 0) {
430 tty_ldisc_put(old->ops); 472 tty_ldisc_put(old);
431 /* This driver is always present */ 473 /* This driver is always present */
432 if (tty_ldisc_get(N_TTY, &new_ldisc) < 0) 474 new_ldisc =tty_ldisc_get(N_TTY);
475 if (IS_ERR(new_ldisc))
433 panic("n_tty: get"); 476 panic("n_tty: get");
434 tty_ldisc_assign(tty, &new_ldisc); 477 tty_ldisc_assign(tty, new_ldisc);
435 tty_set_termios_ldisc(tty, N_TTY); 478 tty_set_termios_ldisc(tty, N_TTY);
436 if (new_ldisc.ops->open) { 479 r = tty_ldisc_open(tty, new_ldisc);
437 int r = new_ldisc.ops->open(tty); 480 if (r < 0)
438 if (r < 0) 481 panic("Couldn't open N_TTY ldisc for "
439 panic("Couldn't open N_TTY ldisc for " 482 "%s --- error %d.",
440 "%s --- error %d.", 483 tty_name(tty, buf), r);
441 tty_name(tty, buf), r);
442 }
443 } 484 }
444} 485}
445 486
446/** 487/**
447 * tty_ldisc_halt - shutdown the line discipline 488 * tty_ldisc_halt - shut down the line discipline
448 * @tty: tty device 489 * @tty: tty device
449 * 490 *
450 * Shut down the line discipline and work queue for this tty device. 491 * Shut down the line discipline and work queue for this tty device.
@@ -456,14 +497,10 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
456 * tty_ldisc_wait_idle. 497 * tty_ldisc_wait_idle.
457 */ 498 */
458 499
459static void tty_ldisc_halt(struct tty_struct *tty) 500static int tty_ldisc_halt(struct tty_struct *tty)
460{ 501{
461 clear_bit(TTY_LDISC, &tty->flags); 502 clear_bit(TTY_LDISC, &tty->flags);
462 cancel_delayed_work(&tty->buf.work); 503 return cancel_delayed_work(&tty->buf.work);
463 /*
464 * Wait for ->hangup_work and ->buf.work handlers to terminate
465 */
466 flush_scheduled_work();
467} 504}
468 505
469/** 506/**
@@ -473,18 +510,22 @@ static void tty_ldisc_halt(struct tty_struct *tty)
473 * Wait for the line discipline to become idle. The discipline must 510 * Wait for the line discipline to become idle. The discipline must
474 * have been halted for this to guarantee it remains idle. 511 * have been halted for this to guarantee it remains idle.
475 * 512 *
513 * tty_ldisc_lock protects the ref counts currently.
476 */ 514 */
477 515
478static void tty_ldisc_wait_idle(struct tty_struct *tty) 516static int tty_ldisc_wait_idle(struct tty_struct *tty)
479{ 517{
480 unsigned long flags; 518 unsigned long flags;
481 spin_lock_irqsave(&tty_ldisc_lock, flags); 519 spin_lock_irqsave(&tty_ldisc_lock, flags);
482 while (tty->ldisc.refcount) { 520 while (tty->ldisc->refcount) {
483 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 521 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
484 wait_event(tty_ldisc_wait, tty->ldisc.refcount == 0); 522 if (wait_event_timeout(tty_ldisc_wait,
523 tty->ldisc->refcount == 0, 5 * HZ) == 0)
524 return -EBUSY;
485 spin_lock_irqsave(&tty_ldisc_lock, flags); 525 spin_lock_irqsave(&tty_ldisc_lock, flags);
486 } 526 }
487 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 527 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
528 return 0;
488} 529}
489 530
490/** 531/**
@@ -493,39 +534,64 @@ static void tty_ldisc_wait_idle(struct tty_struct *tty)
493 * @ldisc: the line discipline 534 * @ldisc: the line discipline
494 * 535 *
495 * Set the discipline of a tty line. Must be called from a process 536 * Set the discipline of a tty line. Must be called from a process
496 * context. 537 * context. The ldisc change logic has to protect itself against any
538 * overlapping ldisc change (including on the other end of pty pairs),
539 * the close of one side of a tty/pty pair, and eventually hangup.
497 * 540 *
498 * Locking: takes tty_ldisc_lock. 541 * Locking: takes tty_ldisc_lock, termios_mutex
499 * called functions take termios_mutex
500 */ 542 */
501 543
502int tty_set_ldisc(struct tty_struct *tty, int ldisc) 544int tty_set_ldisc(struct tty_struct *tty, int ldisc)
503{ 545{
504 int retval; 546 int retval;
505 struct tty_ldisc o_ldisc, new_ldisc; 547 struct tty_ldisc *o_ldisc, *new_ldisc;
506 int work; 548 int work, o_work = 0;
507 unsigned long flags;
508 struct tty_struct *o_tty; 549 struct tty_struct *o_tty;
509 550
510restart: 551 new_ldisc = tty_ldisc_get(ldisc);
511 /* This is a bit ugly for now but means we can break the 'ldisc 552 if (IS_ERR(new_ldisc))
512 is part of the tty struct' assumption later */ 553 return PTR_ERR(new_ldisc);
513 retval = tty_ldisc_get(ldisc, &new_ldisc);
514 if (retval)
515 return retval;
516 554
517 /* 555 /*
518 * Problem: What do we do if this blocks ? 556 * We need to look at the tty locking here for pty/tty pairs
557 * when both sides try to change in parallel.
519 */ 558 */
520 559
521 tty_wait_until_sent(tty, 0); 560 o_tty = tty->link; /* o_tty is the pty side or NULL */
561
522 562
523 if (tty->ldisc.ops->num == ldisc) { 563 /*
524 tty_ldisc_put(new_ldisc.ops); 564 * Check the no-op case
565 */
566
567 if (tty->ldisc->ops->num == ldisc) {
568 tty_ldisc_put(new_ldisc);
525 return 0; 569 return 0;
526 } 570 }
527 571
528 /* 572 /*
573 * Problem: What do we do if this blocks ?
574 * We could deadlock here
575 */
576
577 tty_wait_until_sent(tty, 0);
578
579 mutex_lock(&tty->ldisc_mutex);
580
581 /*
582 * We could be midstream of another ldisc change which has
583 * dropped the lock during processing. If so we need to wait.
584 */
585
586 while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) {
587 mutex_unlock(&tty->ldisc_mutex);
588 wait_event(tty_ldisc_wait,
589 test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
590 mutex_lock(&tty->ldisc_mutex);
591 }
592 set_bit(TTY_LDISC_CHANGING, &tty->flags);
593
594 /*
529 * No more input please, we are switching. The new ldisc 595 * No more input please, we are switching. The new ldisc
530 * will update this value in the ldisc open function 596 * will update this value in the ldisc open function
531 */ 597 */
@@ -533,8 +599,6 @@ restart:
533 tty->receive_room = 0; 599 tty->receive_room = 0;
534 600
535 o_ldisc = tty->ldisc; 601 o_ldisc = tty->ldisc;
536 o_tty = tty->link;
537
538 /* 602 /*
539 * Make sure we don't change while someone holds a 603 * Make sure we don't change while someone holds a
540 * reference to the line discipline. The TTY_LDISC bit 604 * reference to the line discipline. The TTY_LDISC bit
@@ -545,108 +609,181 @@ restart:
545 * with a userspace app continually trying to use the tty in 609 * with a userspace app continually trying to use the tty in
546 * parallel to the change and re-referencing the tty. 610 * parallel to the change and re-referencing the tty.
547 */ 611 */
548 clear_bit(TTY_LDISC, &tty->flags);
549 if (o_tty)
550 clear_bit(TTY_LDISC, &o_tty->flags);
551 612
552 spin_lock_irqsave(&tty_ldisc_lock, flags); 613 work = tty_ldisc_halt(tty);
553 if (tty->ldisc.refcount || (o_tty && o_tty->ldisc.refcount)) {
554 if (tty->ldisc.refcount) {
555 /* Free the new ldisc we grabbed. Must drop the lock
556 first. */
557 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
558 tty_ldisc_put(o_ldisc.ops);
559 /*
560 * There are several reasons we may be busy, including
561 * random momentary I/O traffic. We must therefore
562 * retry. We could distinguish between blocking ops
563 * and retries if we made tty_ldisc_wait() smarter.
564 * That is up for discussion.
565 */
566 if (wait_event_interruptible(tty_ldisc_wait, tty->ldisc.refcount == 0) < 0)
567 return -ERESTARTSYS;
568 goto restart;
569 }
570 if (o_tty && o_tty->ldisc.refcount) {
571 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
572 tty_ldisc_put(o_tty->ldisc.ops);
573 if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
574 return -ERESTARTSYS;
575 goto restart;
576 }
577 }
578 /*
579 * If the TTY_LDISC bit is set, then we are racing against
580 * another ldisc change
581 */
582 if (test_bit(TTY_LDISC_CHANGING, &tty->flags)) {
583 struct tty_ldisc *ld;
584 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
585 tty_ldisc_put(new_ldisc.ops);
586 ld = tty_ldisc_ref_wait(tty);
587 tty_ldisc_deref(ld);
588 goto restart;
589 }
590 /*
591 * This flag is used to avoid two parallel ldisc changes. Once
592 * open and close are fine grained locked this may work better
593 * as a mutex shared with the open/close/hup paths
594 */
595 set_bit(TTY_LDISC_CHANGING, &tty->flags);
596 if (o_tty) 614 if (o_tty)
597 set_bit(TTY_LDISC_CHANGING, &o_tty->flags); 615 o_work = tty_ldisc_halt(o_tty);
598 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
599
600 /*
601 * From this point on we know nobody has an ldisc
602 * usage reference, nor can they obtain one until
603 * we say so later on.
604 */
605 616
606 work = cancel_delayed_work(&tty->buf.work);
607 /* 617 /*
608 * Wait for ->hangup_work and ->buf.work handlers to terminate 618 * Wait for ->hangup_work and ->buf.work handlers to terminate.
609 * MUST NOT hold locks here. 619 * We must drop the mutex here in case a hangup is also in process.
610 */ 620 */
621
622 mutex_unlock(&tty->ldisc_mutex);
623
611 flush_scheduled_work(); 624 flush_scheduled_work();
625
626 /* Let any existing reference holders finish */
627 retval = tty_ldisc_wait_idle(tty);
628 if (retval < 0) {
629 clear_bit(TTY_LDISC_CHANGING, &tty->flags);
630 tty_ldisc_put(new_ldisc);
631 return retval;
632 }
633
634 mutex_lock(&tty->ldisc_mutex);
635 if (test_bit(TTY_HUPPED, &tty->flags)) {
636 /* We were raced by the hangup method. It will have stomped
637 the ldisc data and closed the ldisc down */
638 clear_bit(TTY_LDISC_CHANGING, &tty->flags);
639 mutex_unlock(&tty->ldisc_mutex);
640 tty_ldisc_put(new_ldisc);
641 return -EIO;
642 }
643
612 /* Shutdown the current discipline. */ 644 /* Shutdown the current discipline. */
613 if (o_ldisc.ops->close) 645 tty_ldisc_close(tty, o_ldisc);
614 (o_ldisc.ops->close)(tty);
615 646
616 /* Now set up the new line discipline. */ 647 /* Now set up the new line discipline. */
617 tty_ldisc_assign(tty, &new_ldisc); 648 tty_ldisc_assign(tty, new_ldisc);
618 tty_set_termios_ldisc(tty, ldisc); 649 tty_set_termios_ldisc(tty, ldisc);
619 if (new_ldisc.ops->open) 650
620 retval = (new_ldisc.ops->open)(tty); 651 retval = tty_ldisc_open(tty, new_ldisc);
621 if (retval < 0) { 652 if (retval < 0) {
622 tty_ldisc_put(new_ldisc.ops); 653 /* Back to the old one or N_TTY if we can't */
623 tty_ldisc_restore(tty, &o_ldisc); 654 tty_ldisc_put(new_ldisc);
655 tty_ldisc_restore(tty, o_ldisc);
624 } 656 }
657
625 /* At this point we hold a reference to the new ldisc and a 658 /* At this point we hold a reference to the new ldisc and a
626 a reference to the old ldisc. If we ended up flipping back 659 a reference to the old ldisc. If we ended up flipping back
627 to the existing ldisc we have two references to it */ 660 to the existing ldisc we have two references to it */
628 661
629 if (tty->ldisc.ops->num != o_ldisc.ops->num && tty->ops->set_ldisc) 662 if (tty->ldisc->ops->num != o_ldisc->ops->num && tty->ops->set_ldisc)
630 tty->ops->set_ldisc(tty); 663 tty->ops->set_ldisc(tty);
631 664
632 tty_ldisc_put(o_ldisc.ops); 665 tty_ldisc_put(o_ldisc);
633 666
634 /* 667 /*
635 * Allow ldisc referencing to occur as soon as the driver 668 * Allow ldisc referencing to occur again
636 * ldisc callback completes.
637 */ 669 */
638 670
639 tty_ldisc_enable(tty); 671 tty_ldisc_enable(tty);
640 if (o_tty) 672 if (o_tty)
641 tty_ldisc_enable(o_tty); 673 tty_ldisc_enable(o_tty);
642 674
643 /* Restart it in case no characters kick it off. Safe if 675 /* Restart the work queue in case no characters kick it off. Safe if
644 already running */ 676 already running */
645 if (work) 677 if (work)
646 schedule_delayed_work(&tty->buf.work, 1); 678 schedule_delayed_work(&tty->buf.work, 1);
679 if (o_work)
680 schedule_delayed_work(&o_tty->buf.work, 1);
681 mutex_unlock(&tty->ldisc_mutex);
647 return retval; 682 return retval;
648} 683}
649 684
685/**
686 * tty_reset_termios - reset terminal state
687 * @tty: tty to reset
688 *
689 * Restore a terminal to the driver default state.
690 */
691
692static void tty_reset_termios(struct tty_struct *tty)
693{
694 mutex_lock(&tty->termios_mutex);
695 *tty->termios = tty->driver->init_termios;
696 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
697 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
698 mutex_unlock(&tty->termios_mutex);
699}
700
701
702/**
703 * tty_ldisc_reinit - reinitialise the tty ldisc
704 * @tty: tty to reinit
705 *
706 * Switch the tty back to N_TTY line discipline and leave the
707 * ldisc state closed
708 */
709
710static void tty_ldisc_reinit(struct tty_struct *tty)
711{
712 struct tty_ldisc *ld;
713
714 tty_ldisc_close(tty, tty->ldisc);
715 tty_ldisc_put(tty->ldisc);
716 tty->ldisc = NULL;
717 /*
718 * Switch the line discipline back
719 */
720 ld = tty_ldisc_get(N_TTY);
721 BUG_ON(IS_ERR(ld));
722 tty_ldisc_assign(tty, ld);
723 tty_set_termios_ldisc(tty, N_TTY);
724}
725
726/**
727 * tty_ldisc_hangup - hangup ldisc reset
728 * @tty: tty being hung up
729 *
730 * Some tty devices reset their termios when they receive a hangup
731 * event. In that situation we must also switch back to N_TTY properly
732 * before we reset the termios data.
733 *
734 * Locking: We can take the ldisc mutex as the rest of the code is
735 * careful to allow for this.
736 *
737 * In the pty pair case this occurs in the close() path of the
738 * tty itself so we must be careful about locking rules.
739 */
740
741void tty_ldisc_hangup(struct tty_struct *tty)
742{
743 struct tty_ldisc *ld;
744
745 /*
746 * FIXME! What are the locking issues here? This may me overdoing
747 * things... This question is especially important now that we've
748 * removed the irqlock.
749 */
750 ld = tty_ldisc_ref(tty);
751 if (ld != NULL) {
752 /* We may have no line discipline at this point */
753 if (ld->ops->flush_buffer)
754 ld->ops->flush_buffer(tty);
755 tty_driver_flush_buffer(tty);
756 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
757 ld->ops->write_wakeup)
758 ld->ops->write_wakeup(tty);
759 if (ld->ops->hangup)
760 ld->ops->hangup(tty);
761 tty_ldisc_deref(ld);
762 }
763 /*
764 * FIXME: Once we trust the LDISC code better we can wait here for
765 * ldisc completion and fix the driver call race
766 */
767 wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
768 wake_up_interruptible_poll(&tty->read_wait, POLLIN);
769 /*
770 * Shutdown the current line discipline, and reset it to
771 * N_TTY.
772 */
773 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
774 /* Avoid racing set_ldisc */
775 mutex_lock(&tty->ldisc_mutex);
776 /* Switch back to N_TTY */
777 tty_ldisc_reinit(tty);
778 /* At this point we have a closed ldisc and we want to
779 reopen it. We could defer this to the next open but
780 it means auditing a lot of other paths so this is a FIXME */
781 WARN_ON(tty_ldisc_open(tty, tty->ldisc));
782 tty_ldisc_enable(tty);
783 mutex_unlock(&tty->ldisc_mutex);
784 tty_reset_termios(tty);
785 }
786}
650 787
651/** 788/**
652 * tty_ldisc_setup - open line discipline 789 * tty_ldisc_setup - open line discipline
@@ -654,24 +791,23 @@ restart:
654 * @o_tty: pair tty for pty/tty pairs 791 * @o_tty: pair tty for pty/tty pairs
655 * 792 *
656 * Called during the initial open of a tty/pty pair in order to set up the 793 * Called during the initial open of a tty/pty pair in order to set up the
657 * line discplines and bind them to the tty. 794 * line disciplines and bind them to the tty. This has no locking issues
795 * as the device isn't yet active.
658 */ 796 */
659 797
660int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) 798int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
661{ 799{
662 struct tty_ldisc *ld = &tty->ldisc; 800 struct tty_ldisc *ld = tty->ldisc;
663 int retval; 801 int retval;
664 802
665 if (ld->ops->open) { 803 retval = tty_ldisc_open(tty, ld);
666 retval = (ld->ops->open)(tty); 804 if (retval)
667 if (retval) 805 return retval;
668 return retval; 806
669 } 807 if (o_tty) {
670 if (o_tty && o_tty->ldisc.ops->open) { 808 retval = tty_ldisc_open(o_tty, o_tty->ldisc);
671 retval = (o_tty->ldisc.ops->open)(o_tty);
672 if (retval) { 809 if (retval) {
673 if (ld->ops->close) 810 tty_ldisc_close(tty, ld);
674 (ld->ops->close)(tty);
675 return retval; 811 return retval;
676 } 812 }
677 tty_ldisc_enable(o_tty); 813 tty_ldisc_enable(o_tty);
@@ -679,34 +815,18 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
679 tty_ldisc_enable(tty); 815 tty_ldisc_enable(tty);
680 return 0; 816 return 0;
681} 817}
682
683static void tty_ldisc_reinit(struct tty_struct *tty)
684{
685 struct tty_ldisc ld;
686
687 if (tty->ldisc.ops->close)
688 (tty->ldisc.ops->close)(tty);
689 tty_ldisc_put(tty->ldisc.ops);
690 /*
691 * Switch the line discipline back
692 */
693 WARN_ON(tty_ldisc_get(N_TTY, &ld));
694 tty_ldisc_assign(tty, &ld);
695 tty_set_termios_ldisc(tty, N_TTY);
696}
697
698/** 818/**
699 * tty_ldisc_release - release line discipline 819 * tty_ldisc_release - release line discipline
700 * @tty: tty being shut down 820 * @tty: tty being shut down
701 * @o_tty: pair tty for pty/tty pairs 821 * @o_tty: pair tty for pty/tty pairs
702 * 822 *
703 * Called during the final close of a tty/pty pair in order to shut down the 823 * Called during the final close of a tty/pty pair in order to shut down the
704 * line discpline layer. 824 * line discpline layer. On exit the ldisc assigned is N_TTY and the
825 * ldisc has not been opened.
705 */ 826 */
706 827
707void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) 828void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
708{ 829{
709
710 /* 830 /*
711 * Prevent flush_to_ldisc() from rescheduling the work for later. Then 831 * Prevent flush_to_ldisc() from rescheduling the work for later. Then
712 * kill any delayed work. As this is the final close it does not 832 * kill any delayed work. As this is the final close it does not
@@ -714,6 +834,7 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
714 */ 834 */
715 835
716 tty_ldisc_halt(tty); 836 tty_ldisc_halt(tty);
837 flush_scheduled_work();
717 838
718 /* 839 /*
719 * Wait for any short term users (we know they are just driver 840 * Wait for any short term users (we know they are just driver
@@ -730,11 +851,9 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
730 */ 851 */
731 852
732 tty_ldisc_reinit(tty); 853 tty_ldisc_reinit(tty);
733 if (o_tty) { 854 /* This will need doing differently if we need to lock */
734 /* FIXME: could o_tty be in setldisc here ? */ 855 if (o_tty)
735 clear_bit(TTY_LDISC, &o_tty->flags); 856 tty_ldisc_release(o_tty, NULL);
736 tty_ldisc_reinit(o_tty);
737 }
738} 857}
739 858
740/** 859/**
@@ -747,10 +866,10 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
747 866
748void tty_ldisc_init(struct tty_struct *tty) 867void tty_ldisc_init(struct tty_struct *tty)
749{ 868{
750 struct tty_ldisc ld; 869 struct tty_ldisc *ld = tty_ldisc_get(N_TTY);
751 if (tty_ldisc_get(N_TTY, &ld) < 0) 870 if (IS_ERR(ld))
752 panic("n_tty: init_tty"); 871 panic("n_tty: init_tty");
753 tty_ldisc_assign(tty, &ld); 872 tty_ldisc_assign(tty, ld);
754} 873}
755 874
756void tty_ldisc_begin(void) 875void tty_ldisc_begin(void)
diff --git a/include/linux/tty.h b/include/linux/tty.h
index f9c13c83790c..1488d8c81aac 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -226,8 +226,11 @@ struct tty_struct {
226 struct tty_driver *driver; 226 struct tty_driver *driver;
227 const struct tty_operations *ops; 227 const struct tty_operations *ops;
228 int index; 228 int index;
229 /* The ldisc objects are protected by tty_ldisc_lock at the moment */ 229
230 struct tty_ldisc ldisc; 230 /* Protects ldisc changes: Lock tty not pty */
231 struct mutex ldisc_mutex;
232 struct tty_ldisc *ldisc;
233
231 struct mutex termios_mutex; 234 struct mutex termios_mutex;
232 spinlock_t ctrl_lock; 235 spinlock_t ctrl_lock;
233 /* Termios values are protected by the termios mutex */ 236 /* Termios values are protected by the termios mutex */
@@ -314,6 +317,7 @@ struct tty_struct {
314#define TTY_CLOSING 7 /* ->close() in progress */ 317#define TTY_CLOSING 7 /* ->close() in progress */
315#define TTY_LDISC 9 /* Line discipline attached */ 318#define TTY_LDISC 9 /* Line discipline attached */
316#define TTY_LDISC_CHANGING 10 /* Line discipline changing */ 319#define TTY_LDISC_CHANGING 10 /* Line discipline changing */
320#define TTY_LDISC_OPEN 11 /* Line discipline is open */
317#define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */ 321#define TTY_HW_COOK_OUT 14 /* Hardware can do output cooking */
318#define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */ 322#define TTY_HW_COOK_IN 15 /* Hardware can do input cooking */
319#define TTY_PTY_LOCK 16 /* pty private */ 323#define TTY_PTY_LOCK 16 /* pty private */
@@ -406,6 +410,7 @@ extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b);
406extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); 410extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *);
407extern void tty_ldisc_deref(struct tty_ldisc *); 411extern void tty_ldisc_deref(struct tty_ldisc *);
408extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *); 412extern struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *);
413extern void tty_ldisc_hangup(struct tty_struct *tty);
409extern const struct file_operations tty_ldiscs_proc_fops; 414extern const struct file_operations tty_ldiscs_proc_fops;
410 415
411extern void tty_wakeup(struct tty_struct *tty); 416extern void tty_wakeup(struct tty_struct *tty);