diff options
-rw-r--r-- | drivers/char/tty_ioctl.c | 13 | ||||
-rw-r--r-- | include/linux/tty_driver.h | 6 |
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 | ||
102 | void tty_throttle(struct tty_struct *tty) | 105 | void 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 | } |
109 | EXPORT_SYMBOL(tty_throttle); | 114 | EXPORT_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 | ||
118 | void tty_unthrottle(struct tty_struct *tty) | 129 | void 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 | } |
124 | EXPORT_SYMBOL(tty_unthrottle); | 137 | EXPORT_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 | * |