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