Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <linux/kmod.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/tty_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #undef LDISC_DEBUG_HANGUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #ifdef LDISC_DEBUG_HANGUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define tty_ldisc_debug(tty, f, args...)	tty_debug(tty, f, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define tty_ldisc_debug(tty, f, args...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /* lockdep nested classes for tty->ldisc_sem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	LDISC_SEM_NORMAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	LDISC_SEM_OTHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *	This guards the refcounted line discipline lists. The lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *	must be taken with irqs off because there are hangup path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *	callers who will do ldisc lookups and cannot sleep.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static DEFINE_RAW_SPINLOCK(tty_ldiscs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) /* Line disc dispatch table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  *	tty_register_ldisc	-	install a line discipline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  *	@disc: ldisc number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  *	@new_ldisc: pointer to the ldisc object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  *	Installs a new line discipline into the kernel. The discipline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  *	is set up as unreferenced and then made available to the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  *	from this point onwards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  *	Locking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  *		takes tty_ldiscs_lock to guard against ldisc races
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (disc < N_TTY || disc >= NR_LDISCS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	tty_ldiscs[disc] = new_ldisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	new_ldisc->num = disc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	new_ldisc->refcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) EXPORT_SYMBOL(tty_register_ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  *	tty_unregister_ldisc	-	unload a line discipline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  *	@disc: ldisc number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  *	Remove a line discipline from the kernel providing it is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  *	currently in use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  *	Locking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  *		takes tty_ldiscs_lock to guard against ldisc races
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) int tty_unregister_ldisc(int disc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (disc < N_TTY || disc >= NR_LDISCS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	if (tty_ldiscs[disc]->refcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		tty_ldiscs[disc] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) EXPORT_SYMBOL(tty_unregister_ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static struct tty_ldisc_ops *get_ldops(int disc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	struct tty_ldisc_ops *ldops, *ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	ret = ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	ldops = tty_ldiscs[disc];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	if (ldops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		ret = ERR_PTR(-EAGAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		if (try_module_get(ldops->owner)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 			ldops->refcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			ret = ldops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static void put_ldops(struct tty_ldisc_ops *ldops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	ldops->refcount--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	module_put(ldops->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  *	tty_ldisc_get		-	take a reference to an ldisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  *	@disc: ldisc number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  *	Takes a reference to a line discipline. Deals with refcounts and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  *	module locking counts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  *	Returns: -EINVAL if the discipline index is not [N_TTY..NR_LDISCS] or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  *			 if the discipline is not registered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  *		 -EAGAIN if request_module() failed to load or register the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  *			 the discipline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  *		 -ENOMEM if allocation failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  *		 Otherwise, returns a pointer to the discipline and bumps the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  *		 ref count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  *	Locking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  *		takes tty_ldiscs_lock to guard against ldisc races
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static int tty_ldisc_autoload = IS_BUILTIN(CONFIG_LDISC_AUTOLOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	struct tty_ldisc *ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	struct tty_ldisc_ops *ldops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (disc < N_TTY || disc >= NR_LDISCS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	 * Get the ldisc ops - we may need to request them to be loaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	 * dynamically and try again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	ldops = get_ldops(disc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	if (IS_ERR(ldops)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		if (!capable(CAP_SYS_MODULE) && !tty_ldisc_autoload)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			return ERR_PTR(-EPERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		request_module("tty-ldisc-%d", disc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		ldops = get_ldops(disc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		if (IS_ERR(ldops))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			return ERR_CAST(ldops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	 * There is no way to handle allocation failure of only 16 bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	 * Let's simplify error handling and save more memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL | __GFP_NOFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	ld->ops = ldops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	ld->tty = tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	return ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  *	tty_ldisc_put		-	release the ldisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  *	Complement of tty_ldisc_get().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) static void tty_ldisc_put(struct tty_ldisc *ld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	if (WARN_ON_ONCE(!ld))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	put_ldops(ld->ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	kfree(ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	return (*pos < NR_LDISCS) ? pos : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static void *tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	(*pos)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	return (*pos < NR_LDISCS) ? pos : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	int i = *(loff_t *)v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	struct tty_ldisc_ops *ldops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	ldops = get_ldops(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (IS_ERR(ldops))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	seq_printf(m, "%-10s %2d\n", ldops->name ? ldops->name : "???", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	put_ldops(ldops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) const struct seq_operations tty_ldiscs_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	.start	= tty_ldiscs_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	.next	= tty_ldiscs_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	.stop	= tty_ldiscs_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	.show	= tty_ldiscs_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)  *	tty_ldisc_ref_wait	-	wait for the tty ldisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)  *	@tty: tty device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)  *	Dereference the line discipline for the terminal and take a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  *	reference to it. If the line discipline is in flux then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  *	wait patiently until it changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  *	Returns: NULL if the tty has been hungup and not re-opened with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  *		 a new file descriptor, otherwise valid ldisc reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  *	Note: Must not be called from an IRQ/timer context. The caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  *	must also be careful not to hold other locks that will deadlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  *	against a discipline change, such as an existing ldisc reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  *	(which we check for)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)  *	Note: a file_operations routine (read/poll/write) should use this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)  *	function to wait for any ldisc lifetime events to finish.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	struct tty_ldisc *ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	ld = tty->ldisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	if (!ld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		ldsem_up_read(&tty->ldisc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	return ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  *	tty_ldisc_ref		-	get the tty ldisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  *	@tty: tty device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  *	Dereference the line discipline for the terminal and take a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)  *	reference to it. If the line discipline is in flux then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)  *	return NULL. Can be called from IRQ and timer functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	struct tty_ldisc *ld = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if (ldsem_down_read_trylock(&tty->ldisc_sem)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		ld = tty->ldisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		if (!ld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			ldsem_up_read(&tty->ldisc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	return ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) EXPORT_SYMBOL_GPL(tty_ldisc_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  *	tty_ldisc_deref		-	free a tty ldisc reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  *	@ld: reference to free up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)  *	Undoes the effect of tty_ldisc_ref or tty_ldisc_ref_wait. May
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)  *	be called in IRQ context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) void tty_ldisc_deref(struct tty_ldisc *ld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	ldsem_up_read(&ld->tty->ldisc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) EXPORT_SYMBOL_GPL(tty_ldisc_deref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) __tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	return ldsem_down_write(&tty->ldisc_sem, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) __tty_ldisc_lock_nested(struct tty_struct *tty, unsigned long timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	return ldsem_down_write_nested(&tty->ldisc_sem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 				       LDISC_SEM_OTHER, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static inline void __tty_ldisc_unlock(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	ldsem_up_write(&tty->ldisc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	/* Kindly asking blocked readers to release the read side */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	set_bit(TTY_LDISC_CHANGING, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	wake_up_interruptible_all(&tty->read_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	wake_up_interruptible_all(&tty->write_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	ret = __tty_ldisc_lock(tty, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	set_bit(TTY_LDISC_HALTED, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) void tty_ldisc_unlock(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	clear_bit(TTY_LDISC_HALTED, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	/* Can be cleared here - ldisc_unlock will wake up writers firstly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	clear_bit(TTY_LDISC_CHANGING, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	__tty_ldisc_unlock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			    unsigned long timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	if (tty < tty2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		ret = __tty_ldisc_lock(tty, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 			ret = __tty_ldisc_lock_nested(tty2, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 				__tty_ldisc_unlock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		/* if this is possible, it has lots of implications */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		WARN_ON_ONCE(tty == tty2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		if (tty2 && tty != tty2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 			ret = __tty_ldisc_lock(tty2, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 			if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 				ret = __tty_ldisc_lock_nested(tty, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 				if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 					__tty_ldisc_unlock(tty2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			ret = __tty_ldisc_lock(tty, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	set_bit(TTY_LDISC_HALTED, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	if (tty2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		set_bit(TTY_LDISC_HALTED, &tty2->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static void tty_ldisc_lock_pair(struct tty_struct *tty, struct tty_struct *tty2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	tty_ldisc_lock_pair_timeout(tty, tty2, MAX_SCHEDULE_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static void tty_ldisc_unlock_pair(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 				  struct tty_struct *tty2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	__tty_ldisc_unlock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	if (tty2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		__tty_ldisc_unlock(tty2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)  *	tty_ldisc_flush	-	flush line discipline queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)  *	@tty: tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)  *	Flush the line discipline queue (if any) and the tty flip buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)  *	for this tty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) void tty_ldisc_flush(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	struct tty_ldisc *ld = tty_ldisc_ref(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	tty_buffer_flush(tty, ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	if (ld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		tty_ldisc_deref(ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) EXPORT_SYMBOL_GPL(tty_ldisc_flush);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)  *	tty_set_termios_ldisc		-	set ldisc field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)  *	@tty: tty structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)  *	@disc: line discipline number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)  *	This is probably overkill for real world processors but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)  *	they are not on hot paths so a little discipline won't do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)  *	any harm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)  *	The line discipline-related tty_struct fields are reset to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)  *	prevent the ldisc driver from re-using stale information for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)  *	the new ldisc instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)  *	Locking: takes termios_rwsem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static void tty_set_termios_ldisc(struct tty_struct *tty, int disc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	down_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	tty->termios.c_line = disc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	up_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	tty->disc_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	tty->receive_room = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)  *	tty_ldisc_open		-	open a line discipline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)  *	@tty: tty we are opening the ldisc on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)  *	@ld: discipline to open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)  *	A helper opening method. Also a convenient debugging and check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)  *	point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)  *	Locking: always called with BTM already held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	if (ld->ops->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)                 /* BTM here locks versus a hangup event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		ret = ld->ops->open(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 			clear_bit(TTY_LDISC_OPEN, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		tty_ldisc_debug(tty, "%p: opened\n", ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)  *	tty_ldisc_close		-	close a line discipline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)  *	@tty: tty we are opening the ldisc on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)  *	@ld: discipline to close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)  *	A helper close method. Also a convenient debugging and check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)  *	point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	lockdep_assert_held_write(&tty->ldisc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	WARN_ON(!test_bit(TTY_LDISC_OPEN, &tty->flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	clear_bit(TTY_LDISC_OPEN, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	if (ld->ops->close)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		ld->ops->close(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	tty_ldisc_debug(tty, "%p: closed\n", ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)  *	tty_ldisc_failto	-	helper for ldisc failback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)  *	@tty: tty to open the ldisc on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)  *	@ld: ldisc we are trying to fail back to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)  *	Helper to try and recover a tty when switching back to the old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)  *	ldisc fails and we need something attached.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static int tty_ldisc_failto(struct tty_struct *tty, int ld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	struct tty_ldisc *disc = tty_ldisc_get(tty, ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	lockdep_assert_held_write(&tty->ldisc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	if (IS_ERR(disc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		return PTR_ERR(disc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	tty->ldisc = disc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	tty_set_termios_ldisc(tty, ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	if ((r = tty_ldisc_open(tty, disc)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		tty_ldisc_put(disc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)  *	tty_ldisc_restore	-	helper for tty ldisc change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)  *	@tty: tty to recover
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)  *	@old: previous ldisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)  *	Restore the previous line discipline or N_TTY when a line discipline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)  *	change fails due to an open error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	/* There is an outstanding reference here so this is safe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	if (tty_ldisc_failto(tty, old->ops->num) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		const char *name = tty_name(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		pr_warn("Falling back ldisc for %s.\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		/* The traditional behaviour is to fall back to N_TTY, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		   want to avoid falling back to N_NULL unless we have no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		   choice to avoid the risk of breaking anything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		if (tty_ldisc_failto(tty, N_TTY) < 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		    tty_ldisc_failto(tty, N_NULL) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 			panic("Couldn't open N_NULL ldisc for %s.", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)  *	tty_set_ldisc		-	set line discipline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)  *	@tty: the terminal to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)  *	@disc: the line discipline number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)  *	Set the discipline of a tty line. Must be called from a process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)  *	context. The ldisc change logic has to protect itself against any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)  *	overlapping ldisc change (including on the other end of pty pairs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)  *	the close of one side of a tty/pty pair, and eventually hangup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) int tty_set_ldisc(struct tty_struct *tty, int disc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	struct tty_ldisc *old_ldisc, *new_ldisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	new_ldisc = tty_ldisc_get(tty, disc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	if (IS_ERR(new_ldisc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		return PTR_ERR(new_ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	tty_lock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	retval = tty_ldisc_lock(tty, 5 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	if (!tty->ldisc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	/* Check the no-op case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	if (tty->ldisc->ops->num == disc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	if (test_bit(TTY_HUPPED, &tty->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		/* We were raced by hangup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		retval = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	old_ldisc = tty->ldisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	/* Shutdown the old discipline. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	tty_ldisc_close(tty, old_ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	/* Now set up the new line discipline. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	tty->ldisc = new_ldisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	tty_set_termios_ldisc(tty, disc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	retval = tty_ldisc_open(tty, new_ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		/* Back to the old one or N_TTY if we can't */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		tty_ldisc_put(new_ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		tty_ldisc_restore(tty, old_ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		down_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		tty->ops->set_ldisc(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 		up_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	/* At this point we hold a reference to the new ldisc and a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	   reference to the old ldisc, or we hold two references to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	   the old ldisc (if it was restored as part of error cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	   above). In either case, releasing a single reference from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	   the old ldisc is correct. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	new_ldisc = old_ldisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	tty_ldisc_unlock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	/* Restart the work queue in case no characters kick it off. Safe if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	   already running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	tty_buffer_restart_work(tty->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	tty_ldisc_put(new_ldisc);	/* drop the extra reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	tty_unlock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) EXPORT_SYMBOL_GPL(tty_set_ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)  *	tty_ldisc_kill	-	teardown ldisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)  *	@tty: tty being released
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)  *	Perform final close of the ldisc and reset tty->ldisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static void tty_ldisc_kill(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	lockdep_assert_held_write(&tty->ldisc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	if (!tty->ldisc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	 * Now kill off the ldisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	tty_ldisc_close(tty, tty->ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	tty_ldisc_put(tty->ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	/* Force an oops if we mess this up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	tty->ldisc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)  *	tty_reset_termios	-	reset terminal state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)  *	@tty: tty to reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)  *	Restore a terminal to the driver default state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static void tty_reset_termios(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	down_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	tty->termios = tty->driver->init_termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	up_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)  *	tty_ldisc_reinit	-	reinitialise the tty ldisc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)  *	@tty: tty to reinit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)  *	@disc: line discipline to reinitialize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)  *	Completely reinitialize the line discipline state, by closing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)  *	current instance, if there is one, and opening a new instance. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)  *	an error occurs opening the new non-N_TTY instance, the instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)  *	is dropped and tty->ldisc reset to NULL. The caller can then retry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)  *	with N_TTY instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)  *	Returns 0 if successful, otherwise error code < 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) int tty_ldisc_reinit(struct tty_struct *tty, int disc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	struct tty_ldisc *ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	lockdep_assert_held_write(&tty->ldisc_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	ld = tty_ldisc_get(tty, disc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	if (IS_ERR(ld)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		BUG_ON(disc == N_TTY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		return PTR_ERR(ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	if (tty->ldisc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		tty_ldisc_close(tty, tty->ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 		tty_ldisc_put(tty->ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	/* switch the line discipline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	tty->ldisc = ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	tty_set_termios_ldisc(tty, disc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	retval = tty_ldisc_open(tty, tty->ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		tty_ldisc_put(tty->ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 		tty->ldisc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)  *	tty_ldisc_hangup		-	hangup ldisc reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)  *	@tty: tty being hung up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)  *	Some tty devices reset their termios when they receive a hangup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)  *	event. In that situation we must also switch back to N_TTY properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)  *	before we reset the termios data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)  *	Locking: We can take the ldisc mutex as the rest of the code is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)  *	careful to allow for this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)  *	In the pty pair case this occurs in the close() path of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)  *	tty itself so we must be careful about locking rules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) void tty_ldisc_hangup(struct tty_struct *tty, bool reinit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	struct tty_ldisc *ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	tty_ldisc_debug(tty, "%p: hangup\n", tty->ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	ld = tty_ldisc_ref(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	if (ld != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 		if (ld->ops->flush_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 			ld->ops->flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 		tty_driver_flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 		if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 		    ld->ops->write_wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 			ld->ops->write_wakeup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		if (ld->ops->hangup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 			ld->ops->hangup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		tty_ldisc_deref(ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	wake_up_interruptible_poll(&tty->read_wait, EPOLLIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	 * Shutdown the current line discipline, and reset it to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	 * N_TTY if need be.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	 * Avoid racing set_ldisc or tty_ldisc_release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	tty_ldisc_lock(tty, MAX_SCHEDULE_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 		tty_reset_termios(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	if (tty->ldisc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 		if (reinit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 			if (tty_ldisc_reinit(tty, tty->termios.c_line) < 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 			    tty_ldisc_reinit(tty, N_TTY) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 				WARN_ON(tty_ldisc_reinit(tty, N_NULL) < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 			tty_ldisc_kill(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	tty_ldisc_unlock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)  *	tty_ldisc_setup			-	open line discipline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)  *	@tty: tty being shut down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)  *	@o_tty: pair tty for pty/tty pairs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)  *	Called during the initial open of a tty/pty pair in order to set up the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)  *	line disciplines and bind them to the tty. This has no locking issues
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)  *	as the device isn't yet active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	int retval = tty_ldisc_open(tty, tty->ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	if (o_tty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		 * Called without o_tty->ldisc_sem held, as o_tty has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		 * just allocated and no one has a reference to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 		retval = tty_ldisc_open(o_tty, o_tty->ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 		if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 			tty_ldisc_close(tty, tty->ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 			return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)  *	tty_ldisc_release		-	release line discipline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)  *	@tty: tty being shut down (or one end of pty pair)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)  *	Called during the final close of a tty or a pty pair in order to shut
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)  *	down the line discpline layer. On exit, each tty's ldisc is NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) void tty_ldisc_release(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	struct tty_struct *o_tty = tty->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	 * Shutdown this line discipline. As this is the final close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 	 * it does not race with the set_ldisc code path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	tty_ldisc_lock_pair(tty, o_tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	tty_ldisc_kill(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	if (o_tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 		tty_ldisc_kill(o_tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	tty_ldisc_unlock_pair(tty, o_tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	/* And the memory resources remaining (buffers, termios) will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	   disposed of when the kref hits zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	tty_ldisc_debug(tty, "released\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) EXPORT_SYMBOL_GPL(tty_ldisc_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)  *	tty_ldisc_init		-	ldisc setup for new tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)  *	@tty: tty being allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)  *	Set up the line discipline objects for a newly allocated tty. Note that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)  *	the tty structure is not completely set up when this call is made.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) int tty_ldisc_init(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 	if (IS_ERR(ld))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 		return PTR_ERR(ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	tty->ldisc = ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)  *	tty_ldisc_deinit	-	ldisc cleanup for new tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)  *	@tty: tty that was allocated recently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)  *	The tty structure must not becompletely set up (tty_ldisc_setup) when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)  *      this call is made.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) void tty_ldisc_deinit(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	/* no ldisc_sem, tty is being destroyed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 	if (tty->ldisc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 		tty_ldisc_put(tty->ldisc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 	tty->ldisc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) static struct ctl_table tty_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 		.procname	= "ldisc_autoload",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 		.data		= &tty_ldisc_autoload,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 		.maxlen		= sizeof(tty_ldisc_autoload),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 		.mode		= 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 		.proc_handler	= proc_dointvec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 		.extra1		= SYSCTL_ZERO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 		.extra2		= SYSCTL_ONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static struct ctl_table tty_dir_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 		.procname	= "tty",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 		.mode		= 0555,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 		.child		= tty_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) static struct ctl_table tty_root_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 		.procname	= "dev",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 		.mode		= 0555,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 		.child		= tty_dir_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) void tty_sysctl_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 	register_sysctl_table(tty_root_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }