diff options
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/tty_ioctl.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index d58b92cc187c..132d452578bb 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -106,6 +106,7 @@ void tty_throttle(struct tty_struct *tty) | |||
106 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && | 106 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && |
107 | tty->ops->throttle) | 107 | tty->ops->throttle) |
108 | tty->ops->throttle(tty); | 108 | tty->ops->throttle(tty); |
109 | tty->flow_change = 0; | ||
109 | mutex_unlock(&tty->termios_mutex); | 110 | mutex_unlock(&tty->termios_mutex); |
110 | } | 111 | } |
111 | EXPORT_SYMBOL(tty_throttle); | 112 | EXPORT_SYMBOL(tty_throttle); |
@@ -129,11 +130,74 @@ void tty_unthrottle(struct tty_struct *tty) | |||
129 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && | 130 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && |
130 | tty->ops->unthrottle) | 131 | tty->ops->unthrottle) |
131 | tty->ops->unthrottle(tty); | 132 | tty->ops->unthrottle(tty); |
133 | tty->flow_change = 0; | ||
132 | mutex_unlock(&tty->termios_mutex); | 134 | mutex_unlock(&tty->termios_mutex); |
133 | } | 135 | } |
134 | EXPORT_SYMBOL(tty_unthrottle); | 136 | EXPORT_SYMBOL(tty_unthrottle); |
135 | 137 | ||
136 | /** | 138 | /** |
139 | * tty_throttle_safe - flow control | ||
140 | * @tty: terminal | ||
141 | * | ||
142 | * Similar to tty_throttle() but will only attempt throttle | ||
143 | * if tty->flow_change is TTY_THROTTLE_SAFE. Prevents an accidental | ||
144 | * throttle due to race conditions when throttling is conditional | ||
145 | * on factors evaluated prior to throttling. | ||
146 | * | ||
147 | * Returns 0 if tty is throttled (or was already throttled) | ||
148 | */ | ||
149 | |||
150 | int tty_throttle_safe(struct tty_struct *tty) | ||
151 | { | ||
152 | int ret = 0; | ||
153 | |||
154 | mutex_lock(&tty->termios_mutex); | ||
155 | if (!test_bit(TTY_THROTTLED, &tty->flags)) { | ||
156 | if (tty->flow_change != TTY_THROTTLE_SAFE) | ||
157 | ret = 1; | ||
158 | else { | ||
159 | __set_bit(TTY_THROTTLED, &tty->flags); | ||
160 | if (tty->ops->throttle) | ||
161 | tty->ops->throttle(tty); | ||
162 | } | ||
163 | } | ||
164 | mutex_unlock(&tty->termios_mutex); | ||
165 | |||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | /** | ||
170 | * tty_unthrottle_safe - flow control | ||
171 | * @tty: terminal | ||
172 | * | ||
173 | * Similar to tty_unthrottle() but will only attempt unthrottle | ||
174 | * if tty->flow_change is TTY_UNTHROTTLE_SAFE. Prevents an accidental | ||
175 | * unthrottle due to race conditions when unthrottling is conditional | ||
176 | * on factors evaluated prior to unthrottling. | ||
177 | * | ||
178 | * Returns 0 if tty is unthrottled (or was already unthrottled) | ||
179 | */ | ||
180 | |||
181 | int tty_unthrottle_safe(struct tty_struct *tty) | ||
182 | { | ||
183 | int ret = 0; | ||
184 | |||
185 | mutex_lock(&tty->termios_mutex); | ||
186 | if (test_bit(TTY_THROTTLED, &tty->flags)) { | ||
187 | if (tty->flow_change != TTY_UNTHROTTLE_SAFE) | ||
188 | ret = 1; | ||
189 | else { | ||
190 | __clear_bit(TTY_THROTTLED, &tty->flags); | ||
191 | if (tty->ops->unthrottle) | ||
192 | tty->ops->unthrottle(tty); | ||
193 | } | ||
194 | } | ||
195 | mutex_unlock(&tty->termios_mutex); | ||
196 | |||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | /** | ||
137 | * tty_wait_until_sent - wait for I/O to finish | 201 | * tty_wait_until_sent - wait for I/O to finish |
138 | * @tty: tty we are waiting for | 202 | * @tty: tty we are waiting for |
139 | * @timeout: how long we will wait | 203 | * @timeout: how long we will wait |