// SPDX-License-Identifier: GPL-2.0
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/kmod.h>
#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>
#include <linux/ratelimit.h>
#include "tty.h"

#undef LDISC_DEBUG_HANGUP

#ifdef LDISC_DEBUG_HANGUP
#define tty_ldisc_debug(tty, f, args...)	tty_debug(tty, f, ##args)
#else
#define tty_ldisc_debug(tty, f, args...)
#endif

/* lockdep nested classes for tty->ldisc_sem */
enum {
	LDISC_SEM_NORMAL,
	LDISC_SEM_OTHER,
};


/*
 *	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.
 */

static DEFINE_RAW_SPINLOCK(tty_ldiscs_lock);
/* Line disc dispatch table */
static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];

/**
 * tty_register_ldisc	-	install a line discipline
 * @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: takes %tty_ldiscs_lock to guard against ldisc races
 */
int tty_register_ldisc(struct tty_ldisc_ops *new_ldisc)
{
	unsigned long flags;
	int ret = 0;

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

	raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
	tty_ldiscs[new_ldisc->num] = new_ldisc;
	raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);

	return ret;
}
EXPORT_SYMBOL(tty_register_ldisc);

/**
 * tty_unregister_ldisc	-	unload a line discipline
 * @ldisc: ldisc number
 *
 * Remove a line discipline from the kernel providing it is not currently in
 * use.
 *
 * Locking: takes %tty_ldiscs_lock to guard against ldisc races
 */

void tty_unregister_ldisc(struct tty_ldisc_ops *ldisc)
{
	unsigned long flags;

	raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
	tty_ldiscs[ldisc->num] = NULL;
	raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
}
EXPORT_SYMBOL(tty_unregister_ldisc);

static struct tty_ldisc_ops *get_ldops(int disc)
{
	unsigned long flags;
	struct tty_ldisc_ops *ldops, *ret;

	raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
	ret = ERR_PTR(-EINVAL);
	ldops = tty_ldiscs[disc];
	if (ldops) {
		ret = ERR_PTR(-EAGAIN);
		if (try_module_get(ldops->owner))
			ret = ldops;
	}
	raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
	return ret;
}

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

	raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
	module_put(ldops->owner);
	raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
}

static int tty_ldisc_autoload = IS_BUILTIN(CONFIG_LDISC_AUTOLOAD);

/**
 * tty_ldisc_get	-	take a reference to an ldisc
 * @tty: tty device
 * @disc: ldisc number
 *
 * Takes a reference to a line discipline. Deals with refcounts and module
 * locking counts. If the discipline is not available, its module loaded, if
 * possible.
 *
 * 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 discipline
 * * -%ENOMEM if allocation failure
 * * Otherwise, returns a pointer to the discipline and bumps the ref count
 *
 * Locking: takes %tty_ldiscs_lock to guard against ldisc races
 */
static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
{
	struct tty_ldisc *ld;
	struct tty_ldisc_ops *ldops;

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

	/*
	 * 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)) {
		if (!capable(CAP_SYS_MODULE) && !tty_ldisc_autoload)
			return ERR_PTR(-EPERM);
		request_module("tty-ldisc-%d", disc);
		ldops = get_ldops(disc);
		if (IS_ERR(ldops))
			return ERR_CAST(ldops);
	}

	/*
	 * There is no way to handle allocation failure of only 16 bytes.
	 * Let's simplify error handling and save more memory.
	 */
	ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL | __GFP_NOFAIL);
	ld->ops = ldops;
	ld->tty = tty;

	return ld;
}

/**
 * tty_ldisc_put	-	release the ldisc
 * @ld: lisdsc to release
 *
 * Complement of tty_ldisc_get().
 */
static void tty_ldisc_put(struct tty_ldisc *ld)
{
	if (WARN_ON_ONCE(!ld))
		return;

	put_ldops(ld->ops);
	kfree(ld);
}

static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
{
	return (*pos < NR_LDISCS) ? pos : NULL;
}

static void *tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
{
	(*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;
	struct tty_ldisc_ops *ldops;

	ldops = get_ldops(i);
	if (IS_ERR(ldops))
		return 0;
	seq_printf(m, "%-10s %2d\n", ldops->name ? ldops->name : "???", i);
	put_ldops(ldops);
	return 0;
}

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,
};

/**
 * 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.
 *
 * Returns: %NULL if the tty has been hungup and not re-opened with a new file
 * descriptor, otherwise valid ldisc reference
 *
 * Note 1: 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).
 *
 * Note 2: a file_operations routine (read/poll/write) should use this function
 * to wait for any ldisc lifetime events to finish.
 */
struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
{
	struct tty_ldisc *ld;

	ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT);
	ld = tty->ldisc;
	if (!ld)
		ldsem_up_read(&tty->ldisc_sem);
	return ld;
}
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)
{
	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;
}
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)
{
	ldsem_up_read(&ld->tty->ldisc_sem);
}
EXPORT_SYMBOL_GPL(tty_ldisc_deref);


static inline int
__tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
{
	return ldsem_down_write(&tty->ldisc_sem, timeout);
}

static inline int
__tty_ldisc_lock_nested(struct tty_struct *tty, unsigned long timeout)
{
	return ldsem_down_write_nested(&tty->ldisc_sem,
				       LDISC_SEM_OTHER, timeout);
}

static inline void __tty_ldisc_unlock(struct tty_struct *tty)
{
	ldsem_up_write(&tty->ldisc_sem);
}

int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
{
	int ret;

	/* Kindly asking blocked readers to release the read side */
	set_bit(TTY_LDISC_CHANGING, &tty->flags);
	wake_up_interruptible_all(&tty->read_wait);
	wake_up_interruptible_all(&tty->write_wait);

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

void tty_ldisc_unlock(struct tty_struct *tty)
{
	clear_bit(TTY_LDISC_HALTED, &tty->flags);
	/* Can be cleared here - ldisc_unlock will wake up writers firstly */
	clear_bit(TTY_LDISC_CHANGING, &tty->flags);
	__tty_ldisc_unlock(tty);
}

static int
tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2,
			    unsigned long timeout)
{
	int ret;

	if (tty < tty2) {
		ret = __tty_ldisc_lock(tty, timeout);
		if (ret) {
			ret = __tty_ldisc_lock_nested(tty2, timeout);
			if (!ret)
				__tty_ldisc_unlock(tty);
		}
	} else {
		/* if this is possible, it has lots of implications */
		WARN_ON_ONCE(tty == tty2);
		if (tty2 && tty != tty2) {
			ret = __tty_ldisc_lock(tty2, timeout);
			if (ret) {
				ret = __tty_ldisc_lock_nested(tty, timeout);
				if (!ret)
					__tty_ldisc_unlock(tty2);
			}
		} else
			ret = __tty_ldisc_lock(tty, timeout);
	}

	if (!ret)
		return -EBUSY;

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

static void tty_ldisc_lock_pair(struct tty_struct *tty, struct tty_struct *tty2)
{
	tty_ldisc_lock_pair_timeout(tty, tty2, MAX_SCHEDULE_TIMEOUT);
}

static void tty_ldisc_unlock_pair(struct tty_struct *tty,
				  struct tty_struct *tty2)
{
	__tty_ldisc_unlock(tty);
	if (tty2)
		__tty_ldisc_unlock(tty2);
}

/**
 * tty_ldisc_flush		-	flush line discipline queue
 * @tty: tty to flush ldisc for
 *
 * Flush the line discipline queue (if any) and the tty flip buffers for this
 * @tty.
 */
void tty_ldisc_flush(struct tty_struct *tty)
{
	struct tty_ldisc *ld = tty_ldisc_ref(tty);

	tty_buffer_flush(tty, ld);
	if (ld)
		tty_ldisc_deref(ld);
}
EXPORT_SYMBOL_GPL(tty_ldisc_flush);

/**
 * tty_set_termios_ldisc	-	set ldisc field
 * @tty: tty structure
 * @disc: line discipline number
 *
 * This is probably overkill for real world processors but they are not on hot
 * paths so a little discipline won't do any harm.
 *
 * The line discipline-related tty_struct fields are reset to prevent the ldisc
 * driver from re-using stale information for the new ldisc instance.
 *
 * Locking: takes termios_rwsem
 */
static void tty_set_termios_ldisc(struct tty_struct *tty, int disc)
{
	down_write(&tty->termios_rwsem);
	tty->termios.c_line = disc;
	up_write(&tty->termios_rwsem);

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

/**
 * 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.
 *
 * Locking: always called with BTM already held.
 */
static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
{
	WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
	if (ld->ops->open) {
		int ret;
		/* BTM here locks versus a hangup event */
		ret = ld->ops->open(tty);
		if (ret)
			clear_bit(TTY_LDISC_OPEN, &tty->flags);

		tty_ldisc_debug(tty, "%p: opened\n", ld);
		return ret;
	}
	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)
{
	lockdep_assert_held_write(&tty->ldisc_sem);
	WARN_ON(!test_bit(TTY_LDISC_OPEN, &tty->flags));
	clear_bit(TTY_LDISC_OPEN, &tty->flags);
	if (ld->ops->close)
		ld->ops->close(tty);
	tty_ldisc_debug(tty, "%p: closed\n", ld);
}

/**
 * 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;

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

/**
 * 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 */
	if (tty_ldisc_failto(tty, old->ops->num) < 0) {
		const char *name = tty_name(tty);

		pr_warn("Falling back ldisc for %s.\n", name);
		/*
		 * 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)
			panic("Couldn't open N_NULL ldisc for %s.", name);
	}
}

/**
 * tty_set_ldisc		-	set line discipline
 * @tty: the terminal to set
 * @disc: the line discipline number
 *
 * Set the discipline of a tty line. Must be called from a process 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.
 */
int tty_set_ldisc(struct tty_struct *tty, int disc)
{
	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);

	tty_lock(tty);
	retval = tty_ldisc_lock(tty, 5 * HZ);
	if (retval)
		goto err;

	if (!tty->ldisc) {
		retval = -EIO;
		goto out;
	}

	/* Check the no-op case */
	if (tty->ldisc->ops->num == disc)
		goto out;

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

	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);
	if (retval < 0) {
		/* Back to the old one or N_TTY if we can't */
		tty_ldisc_put(new_ldisc);
		tty_ldisc_restore(tty, old_ldisc);
	}

	if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) {
		down_read(&tty->termios_rwsem);
		tty->ops->set_ldisc(tty);
		up_read(&tty->termios_rwsem);
	}

	/*
	 * 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;
out:
	tty_ldisc_unlock(tty);

	/*
	 * Restart the work queue in case no characters kick it off. Safe if
	 * already running
	 */
	tty_buffer_restart_work(tty->port);
err:
	tty_ldisc_put(new_ldisc);	/* drop the extra reference */
	tty_unlock(tty);
	return retval;
}
EXPORT_SYMBOL_GPL(tty_set_ldisc);

/**
 * 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)
{
	lockdep_assert_held_write(&tty->ldisc_sem);
	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;
}

/**
 * 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)
{
	down_write(&tty->termios_rwsem);
	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);
	up_write(&tty->termios_rwsem);
}


/**
 * tty_ldisc_reinit	-	reinitialise the tty ldisc
 * @tty: tty to reinit
 * @disc: line discipline to reinitialize
 *
 * Completely reinitialize the line discipline state, by closing the 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.
 *
 * Returns: 0 if successful, otherwise error code < 0
 */
int tty_ldisc_reinit(struct tty_struct *tty, int disc)
{
	struct tty_ldisc *ld;
	int retval;

	lockdep_assert_held_write(&tty->ldisc_sem);
	ld = tty_ldisc_get(tty, disc);
	if (IS_ERR(ld)) {
		BUG_ON(disc == N_TTY);
		return PTR_ERR(ld);
	}

	if (tty->ldisc) {
		tty_ldisc_close(tty, tty->ldisc);
		tty_ldisc_put(tty->ldisc);
	}

	/* switch the line discipline */
	tty->ldisc = ld;
	tty_set_termios_ldisc(tty, disc);
	retval = tty_ldisc_open(tty, tty->ldisc);
	if (retval) {
		tty_ldisc_put(tty->ldisc);
		tty->ldisc = NULL;
	}
	return retval;
}

/**
 * tty_ldisc_hangup	-	hangup ldisc reset
 * @tty: tty being hung up
 * @reinit: whether to re-initialise the tty
 *
 * 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.
 */
void tty_ldisc_hangup(struct tty_struct *tty, bool reinit)
{
	struct tty_ldisc *ld;

	tty_ldisc_debug(tty, "%p: hangup\n", tty->ldisc);

	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);
	}

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

	/*
	 * Shutdown the current line discipline, and reset it to
	 * N_TTY if need be.
	 *
	 * Avoid racing set_ldisc or tty_ldisc_release
	 */
	tty_ldisc_lock(tty, MAX_SCHEDULE_TIMEOUT);

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

	if (tty->ldisc) {
		if (reinit) {
			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);
		} else
			tty_ldisc_kill(tty);
	}
	tty_ldisc_unlock(tty);
}

/**
 * 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 line
 * disciplines and bind them to the @tty. This has no locking issues as the
 * device isn't yet active.
 */
int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
{
	int retval = tty_ldisc_open(tty, tty->ldisc);

	if (retval)
		return retval;

	if (o_tty) {
		/*
		 * Called without o_tty->ldisc_sem held, as o_tty has been
		 * just allocated and no one has a reference to it.
		 */
		retval = tty_ldisc_open(o_tty, o_tty->ldisc);
		if (retval) {
			tty_ldisc_close(tty, tty->ldisc);
			return retval;
		}
	}
	return 0;
}

/**
 * tty_ldisc_release	-	release line discipline
 * @tty: tty being shut down (or one end of pty pair)
 *
 * Called during the final close of a tty or a pty pair in order to shut down
 * the line discpline layer. On exit, each tty's ldisc is %NULL.
 */
void tty_ldisc_release(struct tty_struct *tty)
{
	struct tty_struct *o_tty = tty->link;

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

	tty_ldisc_lock_pair(tty, o_tty);
	tty_ldisc_kill(tty);
	if (o_tty)
		tty_ldisc_kill(o_tty);
	tty_ldisc_unlock_pair(tty, o_tty);

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

	tty_ldisc_debug(tty, "released\n");
}

/**
 * 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.
 */
int tty_ldisc_init(struct tty_struct *tty)
{
	struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY);

	if (IS_ERR(ld))
		return PTR_ERR(ld);
	tty->ldisc = ld;
	return 0;
}

/**
 * tty_ldisc_deinit	-	ldisc cleanup for new tty
 * @tty: tty that was allocated recently
 *
 * The tty structure must not be completely set up (tty_ldisc_setup()) when
 * this call is made.
 */
void tty_ldisc_deinit(struct tty_struct *tty)
{
	/* no ldisc_sem, tty is being destroyed */
	if (tty->ldisc)
		tty_ldisc_put(tty->ldisc);
	tty->ldisc = NULL;
}

static struct ctl_table tty_table[] = {
	{
		.procname	= "ldisc_autoload",
		.data		= &tty_ldisc_autoload,
		.maxlen		= sizeof(tty_ldisc_autoload),
		.mode		= 0644,
		.proc_handler	= proc_dointvec,
		.extra1		= SYSCTL_ZERO,
		.extra2		= SYSCTL_ONE,
	},
	{ }
};

static struct ctl_table tty_dir_table[] = {
	{
		.procname	= "tty",
		.mode		= 0555,
		.child		= tty_table,
	},
	{ }
};

static struct ctl_table tty_root_table[] = {
	{
		.procname	= "dev",
		.mode		= 0555,
		.child		= tty_dir_table,
	},
	{ }
};

void tty_sysctl_init(void)
{
	register_sysctl_table(tty_root_table);
}
