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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * which can be dynamically activated and de-activated by the line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * discipline handling modules (like SLIP).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/termios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/compat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #undef TTY_DEBUG_WAIT_UNTIL_SENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #ifdef TTY_DEBUG_WAIT_UNTIL_SENT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) # define tty_debug_wait_until_sent(tty, f, args...)    tty_debug(tty, f, ##args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) # define tty_debug_wait_until_sent(tty, f, args...)    do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #undef	DEBUG
^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)  * Internal flag options for termios setting behavior
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define TERMIOS_FLUSH	1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define TERMIOS_WAIT	2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define TERMIOS_TERMIO	4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define TERMIOS_OLD	8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  *	tty_chars_in_buffer	-	characters pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  *	@tty: terminal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  *	Return the number of bytes of data in the device private
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  *	output queue. If no private method is supplied there is assumed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  *	to be no queue on the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) int tty_chars_in_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	if (tty->ops->chars_in_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		return tty->ops->chars_in_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) EXPORT_SYMBOL(tty_chars_in_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  *	tty_write_room		-	write queue space
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  *	@tty: terminal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  *	Return the number of bytes that can be queued to this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  *	at the present time. The result should be treated as a guarantee
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  *	and the driver cannot offer a value it later shrinks by more than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  *	the number of bytes written. If no method is provided 2K is always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  *	returned and data may be lost as there will be no flow control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) int tty_write_room(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	if (tty->ops->write_room)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		return tty->ops->write_room(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	return 2048;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) EXPORT_SYMBOL(tty_write_room);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  *	tty_driver_flush_buffer	-	discard internal buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  *	@tty: terminal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  *	Discard the internal output buffer for this device. If no method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  *	is provided then either the buffer cannot be hardware flushed or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  *	there is no buffer driver side.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) void tty_driver_flush_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if (tty->ops->flush_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		tty->ops->flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) EXPORT_SYMBOL(tty_driver_flush_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  *	tty_throttle		-	flow control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  *	@tty: terminal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  *	Indicate that a tty should stop transmitting data down the stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  *	Takes the termios rwsem to protect against parallel throttle/unthrottle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  *	and also to ensure the driver can consistently reference its own
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  *	termios data at this point when implementing software flow control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) void tty_throttle(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	down_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	/* check TTY_THROTTLED first so it indicates our state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	    tty->ops->throttle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		tty->ops->throttle(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	tty->flow_change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	up_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) EXPORT_SYMBOL(tty_throttle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  *	tty_unthrottle		-	flow control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  *	@tty: terminal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  *	Indicate that a tty may continue transmitting data down the stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  *	Takes the termios rwsem to protect against parallel throttle/unthrottle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  *	and also to ensure the driver can consistently reference its own
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  *	termios data at this point when implementing software flow control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  *	Drivers should however remember that the stack can issue a throttle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  *	then change flow control method, then unthrottle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) void tty_unthrottle(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	down_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	    tty->ops->unthrottle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		tty->ops->unthrottle(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	tty->flow_change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	up_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) EXPORT_SYMBOL(tty_unthrottle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  *	tty_throttle_safe	-	flow control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  *	@tty: terminal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  *	Similar to tty_throttle() but will only attempt throttle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  *	if tty->flow_change is TTY_THROTTLE_SAFE. Prevents an accidental
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  *	throttle due to race conditions when throttling is conditional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  *	on factors evaluated prior to throttling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)  *	Returns 0 if tty is throttled (or was already throttled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int tty_throttle_safe(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	mutex_lock(&tty->throttle_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	if (!tty_throttled(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		if (tty->flow_change != TTY_THROTTLE_SAFE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			set_bit(TTY_THROTTLED, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			if (tty->ops->throttle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 				tty->ops->throttle(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	mutex_unlock(&tty->throttle_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  *	tty_unthrottle_safe	-	flow control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  *	@tty: terminal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  *	Similar to tty_unthrottle() but will only attempt unthrottle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  *	if tty->flow_change is TTY_UNTHROTTLE_SAFE. Prevents an accidental
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  *	unthrottle due to race conditions when unthrottling is conditional
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  *	on factors evaluated prior to unthrottling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  *	Returns 0 if tty is unthrottled (or was already unthrottled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int tty_unthrottle_safe(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	mutex_lock(&tty->throttle_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	if (tty_throttled(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		if (tty->flow_change != TTY_UNTHROTTLE_SAFE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			clear_bit(TTY_THROTTLED, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			if (tty->ops->unthrottle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 				tty->ops->unthrottle(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	mutex_unlock(&tty->throttle_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	return ret;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  *	tty_wait_until_sent	-	wait for I/O to finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  *	@tty: tty we are waiting for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  *	@timeout: how long we will wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)  *	Wait for characters pending in a tty driver to hit the wire, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  *	for a timeout to occur (eg due to flow control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  *	Locking: none
^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) void tty_wait_until_sent(struct tty_struct *tty, long timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	tty_debug_wait_until_sent(tty, "wait until sent, timeout=%ld\n", timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	if (!timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		timeout = MAX_SCHEDULE_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	timeout = wait_event_interruptible_timeout(tty->write_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			!tty_chars_in_buffer(tty), timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (timeout <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	if (timeout == MAX_SCHEDULE_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	if (tty->ops->wait_until_sent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		tty->ops->wait_until_sent(tty, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) EXPORT_SYMBOL(tty_wait_until_sent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)  *		Termios Helper Methods
^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) static void unset_locked_termios(struct tty_struct *tty, struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	struct ktermios *termios = &tty->termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	struct ktermios *locked  = &tty->termios_locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	termios->c_line = locked->c_line ? old->c_line : termios->c_line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	for (i = 0; i < NCCS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		termios->c_cc[i] = locked->c_cc[i] ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			old->c_cc[i] : termios->c_cc[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	/* FIXME: What should we do for i/ospeed */
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)  *	tty_termios_copy_hw	-	copy hardware settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)  *	@new: New termios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)  *	@old: Old termios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)  *	Propagate the hardware specific terminal setting bits from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)  *	the old termios structure to the new one. This is used in cases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)  *	where the hardware does not support reconfiguration or as a helper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  *	in some cases where only minimal reconfiguration is supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	/* The bits a dumb device handles in software. Smart devices need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	   to always provide a set_termios method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	new->c_cflag &= HUPCL | CREAD | CLOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	new->c_ispeed = old->c_ispeed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	new->c_ospeed = old->c_ospeed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) EXPORT_SYMBOL(tty_termios_copy_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)  *	tty_termios_hw_change	-	check for setting change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)  *	@a: termios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)  *	@b: termios to compare
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)  *	Check if any of the bits that affect a dumb device have changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)  *	between the two termios structures, or a speed change is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) EXPORT_SYMBOL(tty_termios_hw_change);
^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)  *	tty_set_termios		-	update termios values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)  *	@tty: tty to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)  *	@new_termios: desired new value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)  *	Perform updates to the termios values set on this terminal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)  *	A master pty's termios should never be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)  *	Locking: termios_rwsem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	struct ktermios old_termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	struct tty_ldisc *ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	WARN_ON(tty->driver->type == TTY_DRIVER_TYPE_PTY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		tty->driver->subtype == PTY_TYPE_MASTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	 *	Perform the actual termios internal changes under lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	/* FIXME: we need to decide on some locking/ordering semantics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	   for the set_termios notification eventually */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	down_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	old_termios = tty->termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	tty->termios = *new_termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	unset_locked_termios(tty, &old_termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	if (tty->ops->set_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		tty->ops->set_termios(tty, &old_termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		tty_termios_copy_hw(&tty->termios, &old_termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	ld = tty_ldisc_ref(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	if (ld != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		if (ld->ops->set_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 			ld->ops->set_termios(tty, &old_termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		tty_ldisc_deref(ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	up_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) EXPORT_SYMBOL_GPL(tty_set_termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)  *	set_termios		-	set termios values for a tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)  *	@tty: terminal device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)  *	@arg: user data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)  *	@opt: option information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  *	Helper function to prepare termios data and run necessary other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  *	functions before using tty_set_termios to do the actual changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  *	Locking:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  *		Called functions take ldisc and termios_rwsem locks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	struct ktermios tmp_termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	struct tty_ldisc *ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	int retval = tty_check_change(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	down_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	tmp_termios = tty->termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	up_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	if (opt & TERMIOS_TERMIO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		if (user_termio_to_kernel_termios(&tmp_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 						(struct termio __user *)arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) #ifdef TCGETS2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	} else if (opt & TERMIOS_OLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		if (user_termios_to_kernel_termios_1(&tmp_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 						(struct termios __user *)arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		if (user_termios_to_kernel_termios(&tmp_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 						(struct termios2 __user *)arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	} else if (user_termios_to_kernel_termios(&tmp_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 					(struct termios __user *)arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	/* If old style Bfoo values are used then load c_ispeed/c_ospeed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	 * with the real speed so its unconditionally usable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	ld = tty_ldisc_ref(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	if (ld != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			ld->ops->flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		tty_ldisc_deref(ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	if (opt & TERMIOS_WAIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		tty_wait_until_sent(tty, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	tty_set_termios(tty, &tmp_termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	/* FIXME: Arguably if tmp_termios == tty->termios AND the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	   actual requested termios was not tmp_termios then we may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	   want to return an error as no user requested change has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	   succeeded */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static void copy_termios(struct tty_struct *tty, struct ktermios *kterm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	down_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	*kterm = tty->termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	up_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	down_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	*kterm = tty->termios_locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	up_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static int get_termio(struct tty_struct *tty, struct termio __user *termio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	struct ktermios kterm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	copy_termios(tty, &kterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	if (kernel_termios_to_user_termio(termio, &kterm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	return 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) #ifdef TIOCGETP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)  * These are deprecated, but there is limited support..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)  * The "sg_flags" translation is a joke..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static int get_sgflags(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	int flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	if (!L_ICANON(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		if (L_ISIG(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 			flags |= 0x02;		/* cbreak */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			flags |= 0x20;		/* raw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	if (L_ECHO(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		flags |= 0x08;			/* echo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	if (O_OPOST(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		if (O_ONLCR(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 			flags |= 0x10;		/* crmod */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	return flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	struct sgttyb tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	down_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	tmp.sg_ispeed = tty->termios.c_ispeed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	tmp.sg_ospeed = tty->termios.c_ospeed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	tmp.sg_erase = tty->termios.c_cc[VERASE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	tmp.sg_kill = tty->termios.c_cc[VKILL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	tmp.sg_flags = get_sgflags(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	up_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static void set_sgflags(struct ktermios *termios, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	termios->c_iflag = ICRNL | IXON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	termios->c_oflag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	termios->c_lflag = ISIG | ICANON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	if (flags & 0x02) {	/* cbreak */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		termios->c_iflag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		termios->c_lflag &= ~ICANON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	if (flags & 0x08) {		/* echo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		termios->c_lflag |= ECHO | ECHOE | ECHOK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 				    ECHOCTL | ECHOKE | IEXTEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	if (flags & 0x10) {		/* crmod */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		termios->c_oflag |= OPOST | ONLCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	if (flags & 0x20) {	/* raw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		termios->c_iflag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		termios->c_lflag &= ~(ISIG | ICANON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	if (!(termios->c_lflag & ICANON)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		termios->c_cc[VMIN] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		termios->c_cc[VTIME] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)  *	set_sgttyb		-	set legacy terminal values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)  *	@tty: tty structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)  *	@sgttyb: pointer to old style terminal structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)  *	Updates a terminal from the legacy BSD style terminal information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)  *	structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)  *	Locking: termios_rwsem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	struct sgttyb tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	struct ktermios termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	retval = tty_check_change(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	down_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	termios = tty->termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	termios.c_cc[VERASE] = tmp.sg_erase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	termios.c_cc[VKILL] = tmp.sg_kill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	set_sgflags(&termios, tmp.sg_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	/* Try and encode into Bfoo format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) #ifdef BOTHER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 						termios.c_ospeed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	up_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	tty_set_termios(tty, &termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) #ifdef TIOCGETC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	struct tchars tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	down_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	tmp.t_intrc = tty->termios.c_cc[VINTR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	tmp.t_quitc = tty->termios.c_cc[VQUIT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	tmp.t_startc = tty->termios.c_cc[VSTART];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	tmp.t_stopc = tty->termios.c_cc[VSTOP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	tmp.t_eofc = tty->termios.c_cc[VEOF];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	tmp.t_brkc = tty->termios.c_cc[VEOL2];	/* what is brkc anyway? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	up_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	struct tchars tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	if (copy_from_user(&tmp, tchars, sizeof(tmp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	down_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	tty->termios.c_cc[VINTR] = tmp.t_intrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	tty->termios.c_cc[VQUIT] = tmp.t_quitc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	tty->termios.c_cc[VSTART] = tmp.t_startc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	tty->termios.c_cc[VSTOP] = tmp.t_stopc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	tty->termios.c_cc[VEOF] = tmp.t_eofc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	tty->termios.c_cc[VEOL2] = tmp.t_brkc;	/* what is brkc anyway? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	up_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) #ifdef TIOCGLTC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	struct ltchars tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	down_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	tmp.t_suspc = tty->termios.c_cc[VSUSP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	/* what is dsuspc anyway? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	tmp.t_dsuspc = tty->termios.c_cc[VSUSP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	tmp.t_rprntc = tty->termios.c_cc[VREPRINT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	/* what is flushc anyway? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	tmp.t_flushc = tty->termios.c_cc[VEOL2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	tmp.t_werasc = tty->termios.c_cc[VWERASE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	tmp.t_lnextc = tty->termios.c_cc[VLNEXT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	up_read(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
^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) static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	struct ltchars tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	down_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	tty->termios.c_cc[VSUSP] = tmp.t_suspc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	/* what is dsuspc anyway? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	tty->termios.c_cc[VEOL2] = tmp.t_dsuspc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	tty->termios.c_cc[VREPRINT] = tmp.t_rprntc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	/* what is flushc anyway? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	tty->termios.c_cc[VEOL2] = tmp.t_flushc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	tty->termios.c_cc[VWERASE] = tmp.t_werasc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	tty->termios.c_cc[VLNEXT] = tmp.t_lnextc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	up_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)  *	tty_change_softcar	-	carrier change ioctl helper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)  *	@tty: tty to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)  *	@arg: enable/disable CLOCAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)  *	Perform a change to the CLOCAL state and call into the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)  *	layer to make it visible. All done with the termios rwsem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static int tty_change_softcar(struct tty_struct *tty, int arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	int bit = arg ? CLOCAL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	struct ktermios old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	down_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	old = tty->termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	tty->termios.c_cflag &= ~CLOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	tty->termios.c_cflag |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	if (tty->ops->set_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		tty->ops->set_termios(tty, &old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	if (C_CLOCAL(tty) != bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	up_write(&tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)  *	tty_mode_ioctl		-	mode related ioctls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)  *	@tty: tty for the ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)  *	@file: file pointer for the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)  *	@cmd: command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)  *	@arg: ioctl argument
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)  *	Perform non line discipline specific mode control ioctls. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)  *	is designed to be called by line disciplines to ensure they provide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)  *	consistent mode setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 			unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	struct tty_struct *real_tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	void __user *p = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	struct ktermios kterm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	BUG_ON(file == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	    tty->driver->subtype == PTY_TYPE_MASTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		real_tty = tty->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 		real_tty = tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) #ifdef TIOCGETP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	case TIOCGETP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	case TIOCSETP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	case TIOCSETN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) #ifdef TIOCGETC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	case TIOCGETC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		return get_tchars(real_tty, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	case TIOCSETC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		return set_tchars(real_tty, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) #ifdef TIOCGLTC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	case TIOCGLTC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		return get_ltchars(real_tty, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	case TIOCSLTC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 		return set_ltchars(real_tty, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	case TCSETSF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 		return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	case TCSETSW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 		return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	case TCSETS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		return set_termios(real_tty, p, TERMIOS_OLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) #ifndef TCGETS2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	case TCGETS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 		copy_termios(real_tty, &kterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 			ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	case TCGETS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		copy_termios(real_tty, &kterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 		if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 			ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	case TCGETS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 		copy_termios(real_tty, &kterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 			ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	case TCSETSF2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 		return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	case TCSETSW2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		return set_termios(real_tty, p, TERMIOS_WAIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	case TCSETS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 		return set_termios(real_tty, p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	case TCGETA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		return get_termio(real_tty, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	case TCSETAF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	case TCSETAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	case TCSETA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 		return set_termios(real_tty, p, TERMIOS_TERMIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) #ifndef TCGETS2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	case TIOCGLCKTRMIOS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		copy_termios_locked(real_tty, &kterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 			ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	case TIOCSLCKTRMIOS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 		if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 			return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 		copy_termios_locked(real_tty, &kterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 		if (user_termios_to_kernel_termios(&kterm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 					       (struct termios __user *) arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 		down_write(&real_tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		real_tty->termios_locked = kterm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		up_write(&real_tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	case TIOCGLCKTRMIOS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 		copy_termios_locked(real_tty, &kterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 		if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 			ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	case TIOCSLCKTRMIOS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 		if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 			return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 		copy_termios_locked(real_tty, &kterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 		if (user_termios_to_kernel_termios_1(&kterm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 					       (struct termios __user *) arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 		down_write(&real_tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 		real_tty->termios_locked = kterm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 		up_write(&real_tty->termios_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) #ifdef TCGETX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	case TCGETX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	case TCSETX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	case TCSETXW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	case TCSETXF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	case TIOCGSOFTCAR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 		copy_termios(real_tty, &kterm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 		ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 						(int __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	case TIOCSSOFTCAR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 		if (get_user(arg, (unsigned int __user *) arg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 		return tty_change_softcar(real_tty, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 		return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) EXPORT_SYMBOL_GPL(tty_mode_ioctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /* Caller guarantees ldisc reference is held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) static int __tty_perform_flush(struct tty_struct *tty, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	struct tty_ldisc *ld = tty->ldisc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	switch (arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	case TCIFLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 		if (ld && ld->ops->flush_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 			ld->ops->flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 			tty_unthrottle(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	case TCIOFLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 		if (ld && ld->ops->flush_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 			ld->ops->flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 			tty_unthrottle(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	case TCOFLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 		tty_driver_flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	struct tty_ldisc *ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	int retval = tty_check_change(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 	if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	ld = tty_ldisc_ref_wait(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	retval = __tty_perform_flush(tty, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 	if (ld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 		tty_ldisc_deref(ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) EXPORT_SYMBOL_GPL(tty_perform_flush);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 		       unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 	case TCXONC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 		retval = tty_check_change(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 			return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 		switch (arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 		case TCOOFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 			spin_lock_irq(&tty->flow_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 			if (!tty->flow_stopped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 				tty->flow_stopped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 				__stop_tty(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 			spin_unlock_irq(&tty->flow_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 		case TCOON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 			spin_lock_irq(&tty->flow_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 			if (tty->flow_stopped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 				tty->flow_stopped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 				__start_tty(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 			spin_unlock_irq(&tty->flow_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 		case TCIOFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 			if (STOP_CHAR(tty) != __DISABLED_CHAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 				retval = tty_send_xchar(tty, STOP_CHAR(tty));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 		case TCION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 			if (START_CHAR(tty) != __DISABLED_CHAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 				retval = tty_send_xchar(tty, START_CHAR(tty));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 		return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 	case TCFLSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 		retval = tty_check_change(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 		if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 			return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 		return __tty_perform_flush(tty, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 		/* Try the mode commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 		return tty_mode_ioctl(tty, file, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) EXPORT_SYMBOL(n_tty_ioctl_helper);