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