Linux Audio

Check our new training course

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