aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/tty_ioctl.c13
-rw-r--r--include/linux/tty_driver.h6
2 files changed, 17 insertions, 2 deletions
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 6f4c7d0a53bf..2401dbcbee9c 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -97,14 +97,19 @@ EXPORT_SYMBOL(tty_driver_flush_buffer);
97 * @tty: terminal 97 * @tty: terminal
98 * 98 *
99 * Indicate that a tty should stop transmitting data down the stack. 99 * Indicate that a tty should stop transmitting data down the stack.
100 * Takes the termios mutex to protect against parallel throttle/unthrottle
101 * and also to ensure the driver can consistently reference its own
102 * termios data at this point when implementing software flow control.
100 */ 103 */
101 104
102void tty_throttle(struct tty_struct *tty) 105void tty_throttle(struct tty_struct *tty)
103{ 106{
107 mutex_lock(&tty->termios_mutex);
104 /* check TTY_THROTTLED first so it indicates our state */ 108 /* check TTY_THROTTLED first so it indicates our state */
105 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && 109 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
106 tty->ops->throttle) 110 tty->ops->throttle)
107 tty->ops->throttle(tty); 111 tty->ops->throttle(tty);
112 mutex_unlock(&tty->termios_mutex);
108} 113}
109EXPORT_SYMBOL(tty_throttle); 114EXPORT_SYMBOL(tty_throttle);
110 115
@@ -113,13 +118,21 @@ EXPORT_SYMBOL(tty_throttle);
113 * @tty: terminal 118 * @tty: terminal
114 * 119 *
115 * Indicate that a tty may continue transmitting data down the stack. 120 * Indicate that a tty may continue transmitting data down the stack.
121 * Takes the termios mutex to protect against parallel throttle/unthrottle
122 * and also to ensure the driver can consistently reference its own
123 * termios data at this point when implementing software flow control.
124 *
125 * Drivers should however remember that the stack can issue a throttle,
126 * then change flow control method, then unthrottle.
116 */ 127 */
117 128
118void tty_unthrottle(struct tty_struct *tty) 129void tty_unthrottle(struct tty_struct *tty)
119{ 130{
131 mutex_lock(&tty->termios_mutex);
120 if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && 132 if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
121 tty->ops->unthrottle) 133 tty->ops->unthrottle)
122 tty->ops->unthrottle(tty); 134 tty->ops->unthrottle(tty);
135 mutex_unlock(&tty->termios_mutex);
123} 136}
124EXPORT_SYMBOL(tty_unthrottle); 137EXPORT_SYMBOL(tty_unthrottle);
125 138
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index bcba84ea2d86..3566129384a4 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -127,7 +127,8 @@
127 * the line discipline are close to full, and it should somehow 127 * the line discipline are close to full, and it should somehow
128 * signal that no more characters should be sent to the tty. 128 * signal that no more characters should be sent to the tty.
129 * 129 *
130 * Optional: Always invoke via tty_throttle(); 130 * Optional: Always invoke via tty_throttle(), called under the
131 * termios lock.
131 * 132 *
132 * void (*unthrottle)(struct tty_struct * tty); 133 * void (*unthrottle)(struct tty_struct * tty);
133 * 134 *
@@ -135,7 +136,8 @@
135 * that characters can now be sent to the tty without fear of 136 * that characters can now be sent to the tty without fear of
136 * overrunning the input buffers of the line disciplines. 137 * overrunning the input buffers of the line disciplines.
137 * 138 *
138 * Optional: Always invoke via tty_unthrottle(); 139 * Optional: Always invoke via tty_unthrottle(), called under the
140 * termios lock.
139 * 141 *
140 * void (*stop)(struct tty_struct *tty); 142 * void (*stop)(struct tty_struct *tty);
141 * 143 *