tty_ldisc.c 19.8 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2 3
#include <linux/types.h>
#include <linux/errno.h>
4
#include <linux/kmod.h>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/file.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/bitops.h>
#include <linux/seq_file.h>
#include <linux/uaccess.h>
21
#include <linux/ratelimit.h>
22

23 24 25
#undef LDISC_DEBUG_HANGUP

#ifdef LDISC_DEBUG_HANGUP
26
#define tty_ldisc_debug(tty, f, args...)	tty_debug(tty, f, ##args)
27 28 29 30
#else
#define tty_ldisc_debug(tty, f, args...)
#endif

31 32 33 34 35 36 37
/* lockdep nested classes for tty->ldisc_sem */
enum {
	LDISC_SEM_NORMAL,
	LDISC_SEM_OTHER,
};


38 39 40 41 42 43
/*
 *	This guards the refcounted line discipline lists. The lock
 *	must be taken with irqs off because there are hangup path
 *	callers who will do ldisc lookups and cannot sleep.
 */

44
static DEFINE_RAW_SPINLOCK(tty_ldiscs_lock);
45 46 47 48 49 50 51 52 53 54 55 56 57
/* Line disc dispatch table */
static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];

/**
 *	tty_register_ldisc	-	install a line discipline
 *	@disc: ldisc number
 *	@new_ldisc: pointer to the ldisc object
 *
 *	Installs a new line discipline into the kernel. The discipline
 *	is set up as unreferenced and then made available to the kernel
 *	from this point onwards.
 *
 *	Locking:
58
 *		takes tty_ldiscs_lock to guard against ldisc races
59 60 61 62 63 64 65 66 67 68
 */

int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
{
	unsigned long flags;
	int ret = 0;

	if (disc < N_TTY || disc >= NR_LDISCS)
		return -EINVAL;

69
	raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
70 71 72
	tty_ldiscs[disc] = new_ldisc;
	new_ldisc->num = disc;
	new_ldisc->refcount = 0;
73
	raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
74 75 76 77 78 79 80 81 82 83 84 85 86 87

	return ret;
}
EXPORT_SYMBOL(tty_register_ldisc);

/**
 *	tty_unregister_ldisc	-	unload a line discipline
 *	@disc: ldisc number
 *	@new_ldisc: pointer to the ldisc object
 *
 *	Remove a line discipline from the kernel providing it is not
 *	currently in use.
 *
 *	Locking:
88
 *		takes tty_ldiscs_lock to guard against ldisc races
89 90 91 92 93 94 95 96 97 98
 */

int tty_unregister_ldisc(int disc)
{
	unsigned long flags;
	int ret = 0;

	if (disc < N_TTY || disc >= NR_LDISCS)
		return -EINVAL;

99
	raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
100 101 102 103
	if (tty_ldiscs[disc]->refcount)
		ret = -EBUSY;
	else
		tty_ldiscs[disc] = NULL;
104
	raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
105 106 107 108 109

	return ret;
}
EXPORT_SYMBOL(tty_unregister_ldisc);

110 111 112 113 114
static struct tty_ldisc_ops *get_ldops(int disc)
{
	unsigned long flags;
	struct tty_ldisc_ops *ldops, *ret;

115
	raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
116 117 118 119 120 121 122 123 124
	ret = ERR_PTR(-EINVAL);
	ldops = tty_ldiscs[disc];
	if (ldops) {
		ret = ERR_PTR(-EAGAIN);
		if (try_module_get(ldops->owner)) {
			ldops->refcount++;
			ret = ldops;
		}
	}
125
	raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
126 127 128 129 130 131 132
	return ret;
}

static void put_ldops(struct tty_ldisc_ops *ldops)
{
	unsigned long flags;

133
	raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
134 135
	ldops->refcount--;
	module_put(ldops->owner);
136
	raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
137
}
138 139 140 141 142 143

/**
 *	tty_ldisc_get		-	take a reference to an ldisc
 *	@disc: ldisc number
 *
 *	Takes a reference to a line discipline. Deals with refcounts and
144 145 146 147 148 149 150 151 152 153
 *	module locking counts.
 *
 *	Returns: -EINVAL if the discipline index is not [N_TTY..NR_LDISCS] or
 *			 if the discipline is not registered
 *		 -EAGAIN if request_module() failed to load or register the
 *			 the discipline
 *		 -ENOMEM if allocation failure
 *
 *		 Otherwise, returns a pointer to the discipline and bumps the
 *		 ref count
154 155
 *
 *	Locking:
156
 *		takes tty_ldiscs_lock to guard against ldisc races
157 158
 */

159
static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
160
{
A
Alan Cox 已提交
161
	struct tty_ldisc *ld;
162
	struct tty_ldisc_ops *ldops;
163 164

	if (disc < N_TTY || disc >= NR_LDISCS)
A
Alan Cox 已提交
165
		return ERR_PTR(-EINVAL);
166 167 168 169 170 171 172

	/*
	 * Get the ldisc ops - we may need to request them to be loaded
	 * dynamically and try again.
	 */
	ldops = get_ldops(disc);
	if (IS_ERR(ldops)) {
173
		request_module("tty-ldisc-%d", disc);
174 175 176 177 178 179 180 181 182
		ldops = get_ldops(disc);
		if (IS_ERR(ldops))
			return ERR_CAST(ldops);
	}

	ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
	if (ld == NULL) {
		put_ldops(ldops);
		return ERR_PTR(-ENOMEM);
183
	}
184 185

	ld->ops = ldops;
186
	ld->tty = tty;
187

A
Alan Cox 已提交
188
	return ld;
189 190
}

191 192 193 194 195
/**
 *	tty_ldisc_put		-	release the ldisc
 *
 *	Complement of tty_ldisc_get().
 */
196
static void tty_ldisc_put(struct tty_ldisc *ld)
197 198 199 200
{
	if (WARN_ON_ONCE(!ld))
		return;

201
	put_ldops(ld->ops);
202 203 204
	kfree(ld);
}

A
Alan Cox 已提交
205
static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
206 207 208 209
{
	return (*pos < NR_LDISCS) ? pos : NULL;
}

A
Alan Cox 已提交
210
static void *tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
211 212 213 214 215 216 217 218 219 220 221 222
{
	(*pos)++;
	return (*pos < NR_LDISCS) ? pos : NULL;
}

static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
{
}

static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
{
	int i = *(loff_t *)v;
223
	struct tty_ldisc_ops *ldops;
A
Alan Cox 已提交
224

225 226
	ldops = get_ldops(i);
	if (IS_ERR(ldops))
227
		return 0;
228 229
	seq_printf(m, "%-10s %2d\n", ldops->name ? ldops->name : "???", i);
	put_ldops(ldops);
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
	return 0;
}

static const struct seq_operations tty_ldiscs_seq_ops = {
	.start	= tty_ldiscs_seq_start,
	.next	= tty_ldiscs_seq_next,
	.stop	= tty_ldiscs_seq_stop,
	.show	= tty_ldiscs_seq_show,
};

static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &tty_ldiscs_seq_ops);
}

const struct file_operations tty_ldiscs_proc_fops = {
	.owner		= THIS_MODULE,
	.open		= proc_tty_ldiscs_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

/**
 *	tty_ldisc_ref_wait	-	wait for the tty ldisc
 *	@tty: tty device
 *
 *	Dereference the line discipline for the terminal and take a
 *	reference to it. If the line discipline is in flux then
 *	wait patiently until it changes.
 *
261 262 263
 *	Returns: NULL if the tty has been hungup and not re-opened with
 *		 a new file descriptor, otherwise valid ldisc reference
 *
264 265 266 267 268
 *	Note: Must not be called from an IRQ/timer context. The caller
 *	must also be careful not to hold other locks that will deadlock
 *	against a discipline change, such as an existing ldisc reference
 *	(which we check for)
 *
269 270
 *	Note: a file_operations routine (read/poll/write) should use this
 *	function to wait for any ldisc lifetime events to finish.
271 272 273 274
 */

struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
{
275 276
	struct tty_ldisc *ld;

277
	ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT);
278 279
	ld = tty->ldisc;
	if (!ld)
P
Peter Hurley 已提交
280
		ldsem_up_read(&tty->ldisc_sem);
281
	return ld;
282 283 284 285 286 287 288 289 290 291 292 293 294 295
}
EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);

/**
 *	tty_ldisc_ref		-	get the tty ldisc
 *	@tty: tty device
 *
 *	Dereference the line discipline for the terminal and take a
 *	reference to it. If the line discipline is in flux then
 *	return NULL. Can be called from IRQ and timer functions.
 */

struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
{
296 297 298 299 300 301 302 303
	struct tty_ldisc *ld = NULL;

	if (ldsem_down_read_trylock(&tty->ldisc_sem)) {
		ld = tty->ldisc;
		if (!ld)
			ldsem_up_read(&tty->ldisc_sem);
	}
	return ld;
304 305 306 307 308 309 310 311 312 313 314 315 316
}
EXPORT_SYMBOL_GPL(tty_ldisc_ref);

/**
 *	tty_ldisc_deref		-	free a tty ldisc reference
 *	@ld: reference to free up
 *
 *	Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May
 *	be called in IRQ context.
 */

void tty_ldisc_deref(struct tty_ldisc *ld)
{
317
	ldsem_up_read(&ld->tty->ldisc_sem);
318 319 320
}
EXPORT_SYMBOL_GPL(tty_ldisc_deref);

321

322
static inline int
323
__tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
324 325 326 327
{
	return ldsem_down_write(&tty->ldisc_sem, timeout);
}

328
static inline int
329
__tty_ldisc_lock_nested(struct tty_struct *tty, unsigned long timeout)
330 331 332 333 334
{
	return ldsem_down_write_nested(&tty->ldisc_sem,
				       LDISC_SEM_OTHER, timeout);
}

335
static inline void __tty_ldisc_unlock(struct tty_struct *tty)
336
{
337
	ldsem_up_write(&tty->ldisc_sem);
338 339
}

340
int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
P
Peter Hurley 已提交
341 342 343 344 345 346 347 348 349 350
{
	int ret;

	ret = __tty_ldisc_lock(tty, timeout);
	if (!ret)
		return -EBUSY;
	set_bit(TTY_LDISC_HALTED, &tty->flags);
	return 0;
}

351
void tty_ldisc_unlock(struct tty_struct *tty)
P
Peter Hurley 已提交
352 353 354 355 356
{
	clear_bit(TTY_LDISC_HALTED, &tty->flags);
	__tty_ldisc_unlock(tty);
}

357
static int
358 359 360 361 362 363
tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2,
			    unsigned long timeout)
{
	int ret;

	if (tty < tty2) {
364
		ret = __tty_ldisc_lock(tty, timeout);
365
		if (ret) {
366
			ret = __tty_ldisc_lock_nested(tty2, timeout);
367
			if (!ret)
368
				__tty_ldisc_unlock(tty);
369 370 371 372 373
		}
	} else {
		/* if this is possible, it has lots of implications */
		WARN_ON_ONCE(tty == tty2);
		if (tty2 && tty != tty2) {
374
			ret = __tty_ldisc_lock(tty2, timeout);
375
			if (ret) {
376
				ret = __tty_ldisc_lock_nested(tty, timeout);
377
				if (!ret)
378
					__tty_ldisc_unlock(tty2);
379 380
			}
		} else
381
			ret = __tty_ldisc_lock(tty, timeout);
382 383 384 385 386 387 388 389 390 391 392
	}

	if (!ret)
		return -EBUSY;

	set_bit(TTY_LDISC_HALTED, &tty->flags);
	if (tty2)
		set_bit(TTY_LDISC_HALTED, &tty2->flags);
	return 0;
}

393
static void tty_ldisc_lock_pair(struct tty_struct *tty, struct tty_struct *tty2)
394 395 396 397
{
	tty_ldisc_lock_pair_timeout(tty, tty2, MAX_SCHEDULE_TIMEOUT);
}

398 399
static void tty_ldisc_unlock_pair(struct tty_struct *tty,
				  struct tty_struct *tty2)
400
{
401
	__tty_ldisc_unlock(tty);
402
	if (tty2)
403
		__tty_ldisc_unlock(tty2);
404 405
}

A
Alan Cox 已提交
406 407 408 409
/**
 *	tty_ldisc_flush	-	flush line discipline queue
 *	@tty: tty
 *
410 411
 *	Flush the line discipline queue (if any) and the tty flip buffers
 *	for this tty.
A
Alan Cox 已提交
412 413 414 415 416
 */

void tty_ldisc_flush(struct tty_struct *tty)
{
	struct tty_ldisc *ld = tty_ldisc_ref(tty);
417 418 419

	tty_buffer_flush(tty, ld);
	if (ld)
A
Alan Cox 已提交
420 421 422 423
		tty_ldisc_deref(ld);
}
EXPORT_SYMBOL_GPL(tty_ldisc_flush);

424 425 426
/**
 *	tty_set_termios_ldisc		-	set ldisc field
 *	@tty: tty structure
427
 *	@disc: line discipline number
428 429 430 431 432
 *
 *	This is probably overkill for real world processors but
 *	they are not on hot paths so a little discipline won't do
 *	any harm.
 *
433 434 435 436
 *	The line discipline-related tty_struct fields are reset to
 *	prevent the ldisc driver from re-using stale information for
 *	the new ldisc instance.
 *
437
 *	Locking: takes termios_rwsem
438 439
 */

440
static void tty_set_termios_ldisc(struct tty_struct *tty, int disc)
441
{
442
	down_write(&tty->termios_rwsem);
443
	tty->termios.c_line = disc;
444
	up_write(&tty->termios_rwsem);
445 446 447

	tty->disc_data = NULL;
	tty->receive_room = 0;
448 449
}

A
Alan Cox 已提交
450 451 452 453 454 455 456
/**
 *	tty_ldisc_open		-	open a line discipline
 *	@tty: tty we are opening the ldisc on
 *	@ld: discipline to open
 *
 *	A helper opening method. Also a convenient debugging and check
 *	point.
457 458
 *
 *	Locking: always called with BTM already held.
A
Alan Cox 已提交
459 460 461 462 463
 */

static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
{
	WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
464 465
	if (ld->ops->open) {
		int ret;
466
                /* BTM here locks versus a hangup event */
467
		ret = ld->ops->open(tty);
J
Jiri Slaby 已提交
468 469
		if (ret)
			clear_bit(TTY_LDISC_OPEN, &tty->flags);
470

P
Peter Hurley 已提交
471
		tty_ldisc_debug(tty, "%p: opened\n", ld);
472 473
		return ret;
	}
A
Alan Cox 已提交
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
	return 0;
}

/**
 *	tty_ldisc_close		-	close a line discipline
 *	@tty: tty we are opening the ldisc on
 *	@ld: discipline to close
 *
 *	A helper close method. Also a convenient debugging and check
 *	point.
 */

static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
{
	WARN_ON(!test_bit(TTY_LDISC_OPEN, &tty->flags));
	clear_bit(TTY_LDISC_OPEN, &tty->flags);
	if (ld->ops->close)
		ld->ops->close(tty);
P
Peter Hurley 已提交
492
	tty_ldisc_debug(tty, "%p: closed\n", ld);
A
Alan Cox 已提交
493
}
494

495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
/**
 *	tty_ldisc_failto	-	helper for ldisc failback
 *	@tty: tty to open the ldisc on
 *	@ld: ldisc we are trying to fail back to
 *
 *	Helper to try and recover a tty when switching back to the old
 *	ldisc fails and we need something attached.
 */

static int tty_ldisc_failto(struct tty_struct *tty, int ld)
{
	struct tty_ldisc *disc = tty_ldisc_get(tty, ld);
	int r;

	if (IS_ERR(disc))
		return PTR_ERR(disc);
	tty->ldisc = disc;
	tty_set_termios_ldisc(tty, ld);
	if ((r = tty_ldisc_open(tty, disc)) < 0)
		tty_ldisc_put(disc);
	return r;
}

518 519 520 521 522 523 524 525 526 527 528 529
/**
 *	tty_ldisc_restore	-	helper for tty ldisc change
 *	@tty: tty to recover
 *	@old: previous ldisc
 *
 *	Restore the previous line discipline or N_TTY when a line discipline
 *	change fails due to an open error
 */

static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
{
	/* There is an outstanding reference here so this is safe */
530 531 532 533
	if (tty_ldisc_failto(tty, old->ops->num) < 0) {
		const char *name = tty_name(tty);

		pr_warn("Falling back ldisc for %s.\n", name);
534 535 536 537 538
		/* The traditional behaviour is to fall back to N_TTY, we
		   want to avoid falling back to N_NULL unless we have no
		   choice to avoid the risk of breaking anything */
		if (tty_ldisc_failto(tty, N_TTY) < 0 &&
		    tty_ldisc_failto(tty, N_NULL) < 0)
539
			panic("Couldn't open N_NULL ldisc for %s.", name);
540 541 542
	}
}

543 544 545 546 547 548
/**
 *	tty_set_ldisc		-	set line discipline
 *	@tty: the terminal to set
 *	@ldisc: the line discipline
 *
 *	Set the discipline of a tty line. Must be called from a process
A
Alan Cox 已提交
549 550 551
 *	context. The ldisc change logic has to protect itself against any
 *	overlapping ldisc change (including on the other end of pty pairs),
 *	the close of one side of a tty/pty pair, and eventually hangup.
552 553
 */

554
int tty_set_ldisc(struct tty_struct *tty, int disc)
555
{
556 557 558 559 560 561
	int retval;
	struct tty_ldisc *old_ldisc, *new_ldisc;

	new_ldisc = tty_ldisc_get(tty, disc);
	if (IS_ERR(new_ldisc))
		return PTR_ERR(new_ldisc);
562

563
	tty_lock(tty);
P
Peter Hurley 已提交
564
	retval = tty_ldisc_lock(tty, 5 * HZ);
565 566
	if (retval)
		goto err;
567

P
Peter Hurley 已提交
568 569 570 571 572
	if (!tty->ldisc) {
		retval = -EIO;
		goto out;
	}

573
	/* Check the no-op case */
574
	if (tty->ldisc->ops->num == disc)
575
		goto out;
A
Alan Cox 已提交
576

577 578 579 580
	if (test_bit(TTY_HUPPED, &tty->flags)) {
		/* We were raced by hangup */
		retval = -EIO;
		goto out;
581 582
	}

583 584 585 586 587 588 589 590 591 592
	old_ldisc = tty->ldisc;

	/* Shutdown the old discipline. */
	tty_ldisc_close(tty, old_ldisc);

	/* Now set up the new line discipline. */
	tty->ldisc = new_ldisc;
	tty_set_termios_ldisc(tty, disc);

	retval = tty_ldisc_open(tty, new_ldisc);
593
	if (retval < 0) {
A
Alan Cox 已提交
594
		/* Back to the old one or N_TTY if we can't */
595 596
		tty_ldisc_put(new_ldisc);
		tty_ldisc_restore(tty, old_ldisc);
597
	}
A
Alan Cox 已提交
598

599
	if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) {
600
		down_read(&tty->termios_rwsem);
601
		tty->ops->set_ldisc(tty);
602 603
		up_read(&tty->termios_rwsem);
	}
604

605 606 607 608 609 610
	/* At this point we hold a reference to the new ldisc and a
	   reference to the old ldisc, or we hold two references to
	   the old ldisc (if it was restored as part of error cleanup
	   above). In either case, releasing a single reference from
	   the old ldisc is correct. */
	new_ldisc = old_ldisc;
611
out:
P
Peter Hurley 已提交
612
	tty_ldisc_unlock(tty);
613

A
Alan Cox 已提交
614
	/* Restart the work queue in case no characters kick it off. Safe if
615
	   already running */
616
	tty_buffer_restart_work(tty->port);
617
err:
618
	tty_ldisc_put(new_ldisc);	/* drop the extra reference */
A
Alan Cox 已提交
619
	tty_unlock(tty);
620 621
	return retval;
}
622
EXPORT_SYMBOL_GPL(tty_set_ldisc);
623

P
Peter Hurley 已提交
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
/**
 *	tty_ldisc_kill	-	teardown ldisc
 *	@tty: tty being released
 *
 *	Perform final close of the ldisc and reset tty->ldisc
 */
static void tty_ldisc_kill(struct tty_struct *tty)
{
	if (!tty->ldisc)
		return;
	/*
	 * Now kill off the ldisc
	 */
	tty_ldisc_close(tty, tty->ldisc);
	tty_ldisc_put(tty->ldisc);
	/* Force an oops if we mess this up */
	tty->ldisc = NULL;
}

A
Alan Cox 已提交
643 644 645 646 647 648 649 650 651
/**
 *	tty_reset_termios	-	reset terminal state
 *	@tty: tty to reset
 *
 *	Restore a terminal to the driver default state.
 */

static void tty_reset_termios(struct tty_struct *tty)
{
652
	down_write(&tty->termios_rwsem);
653 654 655
	tty->termios = tty->driver->init_termios;
	tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios);
	tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios);
656
	up_write(&tty->termios_rwsem);
A
Alan Cox 已提交
657 658 659 660 661 662
}


/**
 *	tty_ldisc_reinit	-	reinitialise the tty ldisc
 *	@tty: tty to reinit
663
 *	@disc: line discipline to reinitialize
A
Alan Cox 已提交
664
 *
665
 *	Completely reinitialize the line discipline state, by closing the
666 667 668 669
 *	current instance, if there is one, and opening a new instance. If
 *	an error occurs opening the new non-N_TTY instance, the instance
 *	is dropped and tty->ldisc reset to NULL. The caller can then retry
 *	with N_TTY instead.
670 671
 *
 *	Returns 0 if successful, otherwise error code < 0
A
Alan Cox 已提交
672 673
 */

674
int tty_ldisc_reinit(struct tty_struct *tty, int disc)
A
Alan Cox 已提交
675
{
676 677
	struct tty_ldisc *ld;
	int retval;
678

679
	ld = tty_ldisc_get(tty, disc);
680 681
	if (IS_ERR(ld)) {
		BUG_ON(disc == N_TTY);
682
		return PTR_ERR(ld);
683
	}
A
Alan Cox 已提交
684

685 686 687 688 689 690
	if (tty->ldisc) {
		tty_ldisc_close(tty, tty->ldisc);
		tty_ldisc_put(tty->ldisc);
	}

	/* switch the line discipline */
691
	tty->ldisc = ld;
692
	tty_set_termios_ldisc(tty, disc);
693 694
	retval = tty_ldisc_open(tty, tty->ldisc);
	if (retval) {
695 696
		tty_ldisc_put(tty->ldisc);
		tty->ldisc = NULL;
697 698
	}
	return retval;
A
Alan Cox 已提交
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
}

/**
 *	tty_ldisc_hangup		-	hangup ldisc reset
 *	@tty: tty being hung up
 *
 *	Some tty devices reset their termios when they receive a hangup
 *	event. In that situation we must also switch back to N_TTY properly
 *	before we reset the termios data.
 *
 *	Locking: We can take the ldisc mutex as the rest of the code is
 *	careful to allow for this.
 *
 *	In the pty pair case this occurs in the close() path of the
 *	tty itself so we must be careful about locking rules.
 */

716
void tty_ldisc_hangup(struct tty_struct *tty, bool reinit)
A
Alan Cox 已提交
717 718 719
{
	struct tty_ldisc *ld;

P
Peter Hurley 已提交
720
	tty_ldisc_debug(tty, "%p: hangup\n", tty->ldisc);
721

A
Alan Cox 已提交
722 723 724 725 726 727 728 729 730 731 732 733
	ld = tty_ldisc_ref(tty);
	if (ld != NULL) {
		if (ld->ops->flush_buffer)
			ld->ops->flush_buffer(tty);
		tty_driver_flush_buffer(tty);
		if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
		    ld->ops->write_wakeup)
			ld->ops->write_wakeup(tty);
		if (ld->ops->hangup)
			ld->ops->hangup(tty);
		tty_ldisc_deref(ld);
	}
734

735 736
	wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT);
	wake_up_interruptible_poll(&tty->read_wait, EPOLLIN);
737

A
Alan Cox 已提交
738 739
	/*
	 * Shutdown the current line discipline, and reset it to
A
Alan Cox 已提交
740 741 742
	 * N_TTY if need be.
	 *
	 * Avoid racing set_ldisc or tty_ldisc_release
A
Alan Cox 已提交
743
	 */
P
Peter Hurley 已提交
744
	tty_ldisc_lock(tty, MAX_SCHEDULE_TIMEOUT);
A
Arnd Bergmann 已提交
745

746 747
	if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
		tty_reset_termios(tty);
748

749 750
	if (tty->ldisc) {
		if (reinit) {
751 752 753
			if (tty_ldisc_reinit(tty, tty->termios.c_line) < 0 &&
			    tty_ldisc_reinit(tty, N_TTY) < 0)
				WARN_ON(tty_ldisc_reinit(tty, N_NULL) < 0);
754 755
		} else
			tty_ldisc_kill(tty);
A
Alan Cox 已提交
756
	}
P
Peter Hurley 已提交
757
	tty_ldisc_unlock(tty);
A
Alan Cox 已提交
758
}
759 760 761 762 763 764 765

/**
 *	tty_ldisc_setup			-	open line discipline
 *	@tty: tty being shut down
 *	@o_tty: pair tty for pty/tty pairs
 *
 *	Called during the initial open of a tty/pty pair in order to set up the
A
Alan Cox 已提交
766 767
 *	line disciplines and bind them to the tty. This has no locking issues
 *	as the device isn't yet active.
768 769 770 771
 */

int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
{
772
	int retval = tty_ldisc_open(tty, tty->ldisc);
A
Alan Cox 已提交
773 774 775 776 777
	if (retval)
		return retval;

	if (o_tty) {
		retval = tty_ldisc_open(o_tty, o_tty->ldisc);
778
		if (retval) {
779
			tty_ldisc_close(tty, tty->ldisc);
780 781 782 783 784
			return retval;
		}
	}
	return 0;
}
A
Alan Cox 已提交
785

786 787
/**
 *	tty_ldisc_release		-	release line discipline
788
 *	@tty: tty being shut down (or one end of pty pair)
789
 *
790
 *	Called during the final close of a tty or a pty pair in order to shut
791
 *	down the line discpline layer. On exit, each tty's ldisc is NULL.
792 793
 */

794
void tty_ldisc_release(struct tty_struct *tty)
795
{
796 797
	struct tty_struct *o_tty = tty->link;

798
	/*
799 800
	 * Shutdown this line discipline. As this is the final close,
	 * it does not race with the set_ldisc code path.
801 802
	 */

803
	tty_ldisc_lock_pair(tty, o_tty);
A
Alan Cox 已提交
804
	tty_ldisc_kill(tty);
A
Alan Cox 已提交
805
	if (o_tty)
A
Alan Cox 已提交
806
		tty_ldisc_kill(o_tty);
807 808
	tty_ldisc_unlock_pair(tty, o_tty);

809 810
	/* And the memory resources remaining (buffers, termios) will be
	   disposed of when the kref hits zero */
811

812
	tty_ldisc_debug(tty, "released\n");
813
}
814
EXPORT_SYMBOL_GPL(tty_ldisc_release);
815 816 817 818 819 820 821 822 823 824 825

/**
 *	tty_ldisc_init		-	ldisc setup for new tty
 *	@tty: tty being allocated
 *
 *	Set up the line discipline objects for a newly allocated tty. Note that
 *	the tty structure is not completely set up when this call is made.
 */

void tty_ldisc_init(struct tty_struct *tty)
{
826
	struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY);
A
Alan Cox 已提交
827
	if (IS_ERR(ld))
828
		panic("n_tty: init_tty");
829
	tty->ldisc = ld;
830 831
}

832
/**
833
 *	tty_ldisc_deinit	-	ldisc cleanup for new tty
834 835 836 837 838 839 840
 *	@tty: tty that was allocated recently
 *
 *	The tty structure must not becompletely set up (tty_ldisc_setup) when
 *      this call is made.
 */
void tty_ldisc_deinit(struct tty_struct *tty)
{
841 842
	if (tty->ldisc)
		tty_ldisc_put(tty->ldisc);
843
	tty->ldisc = NULL;
844
}