tty_ioctl.c revision 25985edcedea6396277003854657b5f3cb31a628
1/*
2 *  linux/drivers/char/tty_ioctl.c
3 *
4 *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
5 *
6 * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
7 * which can be dynamically activated and de-activated by the line
8 * discipline handling modules (like SLIP).
9 */
10
11#include <linux/types.h>
12#include <linux/termios.h>
13#include <linux/errno.h>
14#include <linux/sched.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
25#include <asm/io.h>
26#include <asm/uaccess.h>
27#include <asm/system.h>
28
29#undef TTY_DEBUG_WAIT_UNTIL_SENT
30
31#undef	DEBUG
32
33/*
34 * Internal flag options for termios setting behavior
35 */
36#define TERMIOS_FLUSH	1
37#define TERMIOS_WAIT	2
38#define TERMIOS_TERMIO	4
39#define TERMIOS_OLD	8
40
41
42/**
43 *	tty_chars_in_buffer	-	characters pending
44 *	@tty: terminal
45 *
46 *	Return the number of bytes of data in the device private
47 *	output queue. If no private method is supplied there is assumed
48 *	to be no queue on the device.
49 */
50
51int tty_chars_in_buffer(struct tty_struct *tty)
52{
53	if (tty->ops->chars_in_buffer)
54		return tty->ops->chars_in_buffer(tty);
55	else
56		return 0;
57}
58EXPORT_SYMBOL(tty_chars_in_buffer);
59
60/**
61 *	tty_write_room		-	write queue space
62 *	@tty: terminal
63 *
64 *	Return the number of bytes that can be queued to this device
65 *	at the present time. The result should be treated as a guarantee
66 *	and the driver cannot offer a value it later shrinks by more than
67 *	the number of bytes written. If no method is provided 2K is always
68 *	returned and data may be lost as there will be no flow control.
69 */
70
71int tty_write_room(struct tty_struct *tty)
72{
73	if (tty->ops->write_room)
74		return tty->ops->write_room(tty);
75	return 2048;
76}
77EXPORT_SYMBOL(tty_write_room);
78
79/**
80 *	tty_driver_flush_buffer	-	discard internal buffer
81 *	@tty: terminal
82 *
83 *	Discard the internal output buffer for this device. If no method
84 *	is provided then either the buffer cannot be hardware flushed or
85 *	there is no buffer driver side.
86 */
87void tty_driver_flush_buffer(struct tty_struct *tty)
88{
89	if (tty->ops->flush_buffer)
90		tty->ops->flush_buffer(tty);
91}
92EXPORT_SYMBOL(tty_driver_flush_buffer);
93
94/**
95 *	tty_throttle		-	flow control
96 *	@tty: terminal
97 *
98 *	Indicate that a tty should stop transmitting data down the stack.
99 *	Takes the termios mutex to protect against parallel throttle/unthrottle
100 *	and also to ensure the driver can consistently reference its own
101 *	termios data at this point when implementing software flow control.
102 */
103
104void tty_throttle(struct tty_struct *tty)
105{
106	mutex_lock(&tty->termios_mutex);
107	/* check TTY_THROTTLED first so it indicates our state */
108	if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
109	    tty->ops->throttle)
110		tty->ops->throttle(tty);
111	mutex_unlock(&tty->termios_mutex);
112}
113EXPORT_SYMBOL(tty_throttle);
114
115/**
116 *	tty_unthrottle		-	flow control
117 *	@tty: terminal
118 *
119 *	Indicate that a tty may continue transmitting data down the stack.
120 *	Takes the termios mutex to protect against parallel throttle/unthrottle
121 *	and also to ensure the driver can consistently reference its own
122 *	termios data at this point when implementing software flow control.
123 *
124 *	Drivers should however remember that the stack can issue a throttle,
125 *	then change flow control method, then unthrottle.
126 */
127
128void tty_unthrottle(struct tty_struct *tty)
129{
130	mutex_lock(&tty->termios_mutex);
131	if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
132	    tty->ops->unthrottle)
133		tty->ops->unthrottle(tty);
134	mutex_unlock(&tty->termios_mutex);
135}
136EXPORT_SYMBOL(tty_unthrottle);
137
138/**
139 *	tty_wait_until_sent	-	wait for I/O to finish
140 *	@tty: tty we are waiting for
141 *	@timeout: how long we will wait
142 *
143 *	Wait for characters pending in a tty driver to hit the wire, or
144 *	for a timeout to occur (eg due to flow control)
145 *
146 *	Locking: none
147 */
148
149void tty_wait_until_sent(struct tty_struct *tty, long timeout)
150{
151#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
152	char buf[64];
153
154	printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
155#endif
156	if (!timeout)
157		timeout = MAX_SCHEDULE_TIMEOUT;
158	if (wait_event_interruptible_timeout(tty->write_wait,
159			!tty_chars_in_buffer(tty), timeout) >= 0) {
160		if (tty->ops->wait_until_sent)
161			tty->ops->wait_until_sent(tty, timeout);
162	}
163}
164EXPORT_SYMBOL(tty_wait_until_sent);
165
166
167/*
168 *		Termios Helper Methods
169 */
170
171static void unset_locked_termios(struct ktermios *termios,
172				 struct ktermios *old,
173				 struct ktermios *locked)
174{
175	int	i;
176
177#define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
178
179	if (!locked) {
180		printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
181		return;
182	}
183
184	NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
185	NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
186	NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
187	NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
188	termios->c_line = locked->c_line ? old->c_line : termios->c_line;
189	for (i = 0; i < NCCS; i++)
190		termios->c_cc[i] = locked->c_cc[i] ?
191			old->c_cc[i] : termios->c_cc[i];
192	/* FIXME: What should we do for i/ospeed */
193}
194
195/*
196 * Routine which returns the baud rate of the tty
197 *
198 * Note that the baud_table needs to be kept in sync with the
199 * include/asm/termbits.h file.
200 */
201static const speed_t baud_table[] = {
202	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
203	9600, 19200, 38400, 57600, 115200, 230400, 460800,
204#ifdef __sparc__
205	76800, 153600, 307200, 614400, 921600
206#else
207	500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
208	2500000, 3000000, 3500000, 4000000
209#endif
210};
211
212#ifndef __sparc__
213static const tcflag_t baud_bits[] = {
214	B0, B50, B75, B110, B134, B150, B200, B300, B600,
215	B1200, B1800, B2400, B4800, B9600, B19200, B38400,
216	B57600, B115200, B230400, B460800, B500000, B576000,
217	B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
218	B3000000, B3500000, B4000000
219};
220#else
221static const tcflag_t baud_bits[] = {
222	B0, B50, B75, B110, B134, B150, B200, B300, B600,
223	B1200, B1800, B2400, B4800, B9600, B19200, B38400,
224	B57600, B115200, B230400, B460800, B76800, B153600,
225	B307200, B614400, B921600
226};
227#endif
228
229static int n_baud_table = ARRAY_SIZE(baud_table);
230
231/**
232 *	tty_termios_baud_rate
233 *	@termios: termios structure
234 *
235 *	Convert termios baud rate data into a speed. This should be called
236 *	with the termios lock held if this termios is a terminal termios
237 *	structure. May change the termios data. Device drivers can call this
238 *	function but should use ->c_[io]speed directly as they are updated.
239 *
240 *	Locking: none
241 */
242
243speed_t tty_termios_baud_rate(struct ktermios *termios)
244{
245	unsigned int cbaud;
246
247	cbaud = termios->c_cflag & CBAUD;
248
249#ifdef BOTHER
250	/* Magic token for arbitrary speed via c_ispeed/c_ospeed */
251	if (cbaud == BOTHER)
252		return termios->c_ospeed;
253#endif
254	if (cbaud & CBAUDEX) {
255		cbaud &= ~CBAUDEX;
256
257		if (cbaud < 1 || cbaud + 15 > n_baud_table)
258			termios->c_cflag &= ~CBAUDEX;
259		else
260			cbaud += 15;
261	}
262	return baud_table[cbaud];
263}
264EXPORT_SYMBOL(tty_termios_baud_rate);
265
266/**
267 *	tty_termios_input_baud_rate
268 *	@termios: termios structure
269 *
270 *	Convert termios baud rate data into a speed. This should be called
271 *	with the termios lock held if this termios is a terminal termios
272 *	structure. May change the termios data. Device drivers can call this
273 *	function but should use ->c_[io]speed directly as they are updated.
274 *
275 *	Locking: none
276 */
277
278speed_t tty_termios_input_baud_rate(struct ktermios *termios)
279{
280#ifdef IBSHIFT
281	unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
282
283	if (cbaud == B0)
284		return tty_termios_baud_rate(termios);
285
286	/* Magic token for arbitrary speed via c_ispeed*/
287	if (cbaud == BOTHER)
288		return termios->c_ispeed;
289
290	if (cbaud & CBAUDEX) {
291		cbaud &= ~CBAUDEX;
292
293		if (cbaud < 1 || cbaud + 15 > n_baud_table)
294			termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
295		else
296			cbaud += 15;
297	}
298	return baud_table[cbaud];
299#else
300	return tty_termios_baud_rate(termios);
301#endif
302}
303EXPORT_SYMBOL(tty_termios_input_baud_rate);
304
305/**
306 *	tty_termios_encode_baud_rate
307 *	@termios: ktermios structure holding user requested state
308 *	@ispeed: input speed
309 *	@ospeed: output speed
310 *
311 *	Encode the speeds set into the passed termios structure. This is
312 *	used as a library helper for drivers os that they can report back
313 *	the actual speed selected when it differs from the speed requested
314 *
315 *	For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
316 *	we need to carefully set the bits when the user does not get the
317 *	desired speed. We allow small margins and preserve as much of possible
318 *	of the input intent to keep compatibility.
319 *
320 *	Locking: Caller should hold termios lock. This is already held
321 *	when calling this function from the driver termios handler.
322 *
323 *	The ifdefs deal with platforms whose owners have yet to update them
324 *	and will all go away once this is done.
325 */
326
327void tty_termios_encode_baud_rate(struct ktermios *termios,
328				  speed_t ibaud, speed_t obaud)
329{
330	int i = 0;
331	int ifound = -1, ofound = -1;
332	int iclose = ibaud/50, oclose = obaud/50;
333	int ibinput = 0;
334
335	if (obaud == 0)			/* CD dropped 		  */
336		ibaud = 0;		/* Clear ibaud to be sure */
337
338	termios->c_ispeed = ibaud;
339	termios->c_ospeed = obaud;
340
341#ifdef BOTHER
342	/* If the user asked for a precise weird speed give a precise weird
343	   answer. If they asked for a Bfoo speed they many have problems
344	   digesting non-exact replies so fuzz a bit */
345
346	if ((termios->c_cflag & CBAUD) == BOTHER)
347		oclose = 0;
348	if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER)
349		iclose = 0;
350	if ((termios->c_cflag >> IBSHIFT) & CBAUD)
351		ibinput = 1;	/* An input speed was specified */
352#endif
353	termios->c_cflag &= ~CBAUD;
354
355	/*
356	 *	Our goal is to find a close match to the standard baud rate
357	 *	returned. Walk the baud rate table and if we get a very close
358	 *	match then report back the speed as a POSIX Bxxxx value by
359	 *	preference
360	 */
361
362	do {
363		if (obaud - oclose <= baud_table[i] &&
364		    obaud + oclose >= baud_table[i]) {
365			termios->c_cflag |= baud_bits[i];
366			ofound = i;
367		}
368		if (ibaud - iclose <= baud_table[i] &&
369		    ibaud + iclose >= baud_table[i]) {
370			/* For the case input == output don't set IBAUD bits
371			   if the user didn't do so */
372			if (ofound == i && !ibinput)
373				ifound  = i;
374#ifdef IBSHIFT
375			else {
376				ifound = i;
377				termios->c_cflag |= (baud_bits[i] << IBSHIFT);
378			}
379#endif
380		}
381	} while (++i < n_baud_table);
382
383	/*
384	 *	If we found no match then use BOTHER if provided or warn
385	 *	the user their platform maintainer needs to wake up if not.
386	 */
387#ifdef BOTHER
388	if (ofound == -1)
389		termios->c_cflag |= BOTHER;
390	/* Set exact input bits only if the input and output differ or the
391	   user already did */
392	if (ifound == -1 && (ibaud != obaud || ibinput))
393		termios->c_cflag |= (BOTHER << IBSHIFT);
394#else
395	if (ifound == -1 || ofound == -1) {
396		printk_once(KERN_WARNING "tty: Unable to return correct "
397			  "speed data as your architecture needs updating.\n");
398	}
399#endif
400}
401EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
402
403/**
404 *	tty_encode_baud_rate		-	set baud rate of the tty
405 *	@ibaud: input baud rate
406 *	@obad: output baud rate
407 *
408 *	Update the current termios data for the tty with the new speed
409 *	settings. The caller must hold the termios_mutex for the tty in
410 *	question.
411 */
412
413void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
414{
415	tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
416}
417EXPORT_SYMBOL_GPL(tty_encode_baud_rate);
418
419/**
420 *	tty_get_baud_rate	-	get tty bit rates
421 *	@tty: tty to query
422 *
423 *	Returns the baud rate as an integer for this terminal. The
424 *	termios lock must be held by the caller and the terminal bit
425 *	flags may be updated.
426 *
427 *	Locking: none
428 */
429
430speed_t tty_get_baud_rate(struct tty_struct *tty)
431{
432	speed_t baud = tty_termios_baud_rate(tty->termios);
433
434	if (baud == 38400 && tty->alt_speed) {
435		if (!tty->warned) {
436			printk(KERN_WARNING "Use of setserial/setrocket to "
437					    "set SPD_* flags is deprecated\n");
438			tty->warned = 1;
439		}
440		baud = tty->alt_speed;
441	}
442
443	return baud;
444}
445EXPORT_SYMBOL(tty_get_baud_rate);
446
447/**
448 *	tty_termios_copy_hw	-	copy hardware settings
449 *	@new: New termios
450 *	@old: Old termios
451 *
452 *	Propagate the hardware specific terminal setting bits from
453 *	the old termios structure to the new one. This is used in cases
454 *	where the hardware does not support reconfiguration or as a helper
455 *	in some cases where only minimal reconfiguration is supported
456 */
457
458void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old)
459{
460	/* The bits a dumb device handles in software. Smart devices need
461	   to always provide a set_termios method */
462	new->c_cflag &= HUPCL | CREAD | CLOCAL;
463	new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL);
464	new->c_ispeed = old->c_ispeed;
465	new->c_ospeed = old->c_ospeed;
466}
467EXPORT_SYMBOL(tty_termios_copy_hw);
468
469/**
470 *	tty_termios_hw_change	-	check for setting change
471 *	@a: termios
472 *	@b: termios to compare
473 *
474 *	Check if any of the bits that affect a dumb device have changed
475 *	between the two termios structures, or a speed change is needed.
476 */
477
478int tty_termios_hw_change(struct ktermios *a, struct ktermios *b)
479{
480	if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
481		return 1;
482	if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL))
483		return 1;
484	return 0;
485}
486EXPORT_SYMBOL(tty_termios_hw_change);
487
488/**
489 *	tty_set_termios		-	update termios values
490 *	@tty: tty to update
491 *	@new_termios: desired new value
492 *
493 *	Perform updates to the termios values set on this terminal. There
494 *	is a bit of layering violation here with n_tty in terms of the
495 *	internal knowledge of this function.
496 *
497 *	Locking: termios_mutex
498 */
499
500int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
501{
502	struct ktermios old_termios;
503	struct tty_ldisc *ld;
504	unsigned long flags;
505
506	/*
507	 *	Perform the actual termios internal changes under lock.
508	 */
509
510
511	/* FIXME: we need to decide on some locking/ordering semantics
512	   for the set_termios notification eventually */
513	mutex_lock(&tty->termios_mutex);
514	old_termios = *tty->termios;
515	*tty->termios = *new_termios;
516	unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
517
518	/* See if packet mode change of state. */
519	if (tty->link && tty->link->packet) {
520		int extproc = (old_termios.c_lflag & EXTPROC) |
521				(tty->termios->c_lflag & EXTPROC);
522		int old_flow = ((old_termios.c_iflag & IXON) &&
523				(old_termios.c_cc[VSTOP] == '\023') &&
524				(old_termios.c_cc[VSTART] == '\021'));
525		int new_flow = (I_IXON(tty) &&
526				STOP_CHAR(tty) == '\023' &&
527				START_CHAR(tty) == '\021');
528		if ((old_flow != new_flow) || extproc) {
529			spin_lock_irqsave(&tty->ctrl_lock, flags);
530			if (old_flow != new_flow) {
531				tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
532				if (new_flow)
533					tty->ctrl_status |= TIOCPKT_DOSTOP;
534				else
535					tty->ctrl_status |= TIOCPKT_NOSTOP;
536			}
537			if (extproc)
538				tty->ctrl_status |= TIOCPKT_IOCTL;
539			spin_unlock_irqrestore(&tty->ctrl_lock, flags);
540			wake_up_interruptible(&tty->link->read_wait);
541		}
542	}
543
544	if (tty->ops->set_termios)
545		(*tty->ops->set_termios)(tty, &old_termios);
546	else
547		tty_termios_copy_hw(tty->termios, &old_termios);
548
549	ld = tty_ldisc_ref(tty);
550	if (ld != NULL) {
551		if (ld->ops->set_termios)
552			(ld->ops->set_termios)(tty, &old_termios);
553		tty_ldisc_deref(ld);
554	}
555	mutex_unlock(&tty->termios_mutex);
556	return 0;
557}
558EXPORT_SYMBOL_GPL(tty_set_termios);
559
560/**
561 *	set_termios		-	set termios values for a tty
562 *	@tty: terminal device
563 *	@arg: user data
564 *	@opt: option information
565 *
566 *	Helper function to prepare termios data and run necessary other
567 *	functions before using tty_set_termios to do the actual changes.
568 *
569 *	Locking:
570 *		Called functions take ldisc and termios_mutex locks
571 */
572
573static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
574{
575	struct ktermios tmp_termios;
576	struct tty_ldisc *ld;
577	int retval = tty_check_change(tty);
578
579	if (retval)
580		return retval;
581
582	mutex_lock(&tty->termios_mutex);
583	memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
584	mutex_unlock(&tty->termios_mutex);
585
586	if (opt & TERMIOS_TERMIO) {
587		if (user_termio_to_kernel_termios(&tmp_termios,
588						(struct termio __user *)arg))
589			return -EFAULT;
590#ifdef TCGETS2
591	} else if (opt & TERMIOS_OLD) {
592		if (user_termios_to_kernel_termios_1(&tmp_termios,
593						(struct termios __user *)arg))
594			return -EFAULT;
595	} else {
596		if (user_termios_to_kernel_termios(&tmp_termios,
597						(struct termios2 __user *)arg))
598			return -EFAULT;
599	}
600#else
601	} else if (user_termios_to_kernel_termios(&tmp_termios,
602					(struct termios __user *)arg))
603		return -EFAULT;
604#endif
605
606	/* If old style Bfoo values are used then load c_ispeed/c_ospeed
607	 * with the real speed so its unconditionally usable */
608	tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
609	tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
610
611	ld = tty_ldisc_ref(tty);
612
613	if (ld != NULL) {
614		if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
615			ld->ops->flush_buffer(tty);
616		tty_ldisc_deref(ld);
617	}
618
619	if (opt & TERMIOS_WAIT) {
620		tty_wait_until_sent(tty, 0);
621		if (signal_pending(current))
622			return -EINTR;
623	}
624
625	tty_set_termios(tty, &tmp_termios);
626
627	/* FIXME: Arguably if tmp_termios == tty->termios AND the
628	   actual requested termios was not tmp_termios then we may
629	   want to return an error as no user requested change has
630	   succeeded */
631	return 0;
632}
633
634static void copy_termios(struct tty_struct *tty, struct ktermios *kterm)
635{
636	mutex_lock(&tty->termios_mutex);
637	memcpy(kterm, tty->termios, sizeof(struct ktermios));
638	mutex_unlock(&tty->termios_mutex);
639}
640
641static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm)
642{
643	mutex_lock(&tty->termios_mutex);
644	memcpy(kterm, tty->termios_locked, sizeof(struct ktermios));
645	mutex_unlock(&tty->termios_mutex);
646}
647
648static int get_termio(struct tty_struct *tty, struct termio __user *termio)
649{
650	struct ktermios kterm;
651	copy_termios(tty, &kterm);
652	if (kernel_termios_to_user_termio(termio, &kterm))
653		return -EFAULT;
654	return 0;
655}
656
657
658#ifdef TCGETX
659
660/**
661 *	set_termiox	-	set termiox fields if possible
662 *	@tty: terminal
663 *	@arg: termiox structure from user
664 *	@opt: option flags for ioctl type
665 *
666 *	Implement the device calling points for the SYS5 termiox ioctl
667 *	interface in Linux
668 */
669
670static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
671{
672	struct termiox tnew;
673	struct tty_ldisc *ld;
674
675	if (tty->termiox == NULL)
676		return -EINVAL;
677	if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
678		return -EFAULT;
679
680	ld = tty_ldisc_ref(tty);
681	if (ld != NULL) {
682		if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
683			ld->ops->flush_buffer(tty);
684		tty_ldisc_deref(ld);
685	}
686	if (opt & TERMIOS_WAIT) {
687		tty_wait_until_sent(tty, 0);
688		if (signal_pending(current))
689			return -EINTR;
690	}
691
692	mutex_lock(&tty->termios_mutex);
693	if (tty->ops->set_termiox)
694		tty->ops->set_termiox(tty, &tnew);
695	mutex_unlock(&tty->termios_mutex);
696	return 0;
697}
698
699#endif
700
701
702#ifdef TIOCGETP
703/*
704 * These are deprecated, but there is limited support..
705 *
706 * The "sg_flags" translation is a joke..
707 */
708static int get_sgflags(struct tty_struct *tty)
709{
710	int flags = 0;
711
712	if (!(tty->termios->c_lflag & ICANON)) {
713		if (tty->termios->c_lflag & ISIG)
714			flags |= 0x02;		/* cbreak */
715		else
716			flags |= 0x20;		/* raw */
717	}
718	if (tty->termios->c_lflag & ECHO)
719		flags |= 0x08;			/* echo */
720	if (tty->termios->c_oflag & OPOST)
721		if (tty->termios->c_oflag & ONLCR)
722			flags |= 0x10;		/* crmod */
723	return flags;
724}
725
726static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
727{
728	struct sgttyb tmp;
729
730	mutex_lock(&tty->termios_mutex);
731	tmp.sg_ispeed = tty->termios->c_ispeed;
732	tmp.sg_ospeed = tty->termios->c_ospeed;
733	tmp.sg_erase = tty->termios->c_cc[VERASE];
734	tmp.sg_kill = tty->termios->c_cc[VKILL];
735	tmp.sg_flags = get_sgflags(tty);
736	mutex_unlock(&tty->termios_mutex);
737
738	return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
739}
740
741static void set_sgflags(struct ktermios *termios, int flags)
742{
743	termios->c_iflag = ICRNL | IXON;
744	termios->c_oflag = 0;
745	termios->c_lflag = ISIG | ICANON;
746	if (flags & 0x02) {	/* cbreak */
747		termios->c_iflag = 0;
748		termios->c_lflag &= ~ICANON;
749	}
750	if (flags & 0x08) {		/* echo */
751		termios->c_lflag |= ECHO | ECHOE | ECHOK |
752				    ECHOCTL | ECHOKE | IEXTEN;
753	}
754	if (flags & 0x10) {		/* crmod */
755		termios->c_oflag |= OPOST | ONLCR;
756	}
757	if (flags & 0x20) {	/* raw */
758		termios->c_iflag = 0;
759		termios->c_lflag &= ~(ISIG | ICANON);
760	}
761	if (!(termios->c_lflag & ICANON)) {
762		termios->c_cc[VMIN] = 1;
763		termios->c_cc[VTIME] = 0;
764	}
765}
766
767/**
768 *	set_sgttyb		-	set legacy terminal values
769 *	@tty: tty structure
770 *	@sgttyb: pointer to old style terminal structure
771 *
772 *	Updates a terminal from the legacy BSD style terminal information
773 *	structure.
774 *
775 *	Locking: termios_mutex
776 */
777
778static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
779{
780	int retval;
781	struct sgttyb tmp;
782	struct ktermios termios;
783
784	retval = tty_check_change(tty);
785	if (retval)
786		return retval;
787
788	if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
789		return -EFAULT;
790
791	mutex_lock(&tty->termios_mutex);
792	termios = *tty->termios;
793	termios.c_cc[VERASE] = tmp.sg_erase;
794	termios.c_cc[VKILL] = tmp.sg_kill;
795	set_sgflags(&termios, tmp.sg_flags);
796	/* Try and encode into Bfoo format */
797#ifdef BOTHER
798	tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
799						termios.c_ospeed);
800#endif
801	mutex_unlock(&tty->termios_mutex);
802	tty_set_termios(tty, &termios);
803	return 0;
804}
805#endif
806
807#ifdef TIOCGETC
808static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
809{
810	struct tchars tmp;
811
812	mutex_lock(&tty->termios_mutex);
813	tmp.t_intrc = tty->termios->c_cc[VINTR];
814	tmp.t_quitc = tty->termios->c_cc[VQUIT];
815	tmp.t_startc = tty->termios->c_cc[VSTART];
816	tmp.t_stopc = tty->termios->c_cc[VSTOP];
817	tmp.t_eofc = tty->termios->c_cc[VEOF];
818	tmp.t_brkc = tty->termios->c_cc[VEOL2];	/* what is brkc anyway? */
819	mutex_unlock(&tty->termios_mutex);
820	return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
821}
822
823static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
824{
825	struct tchars tmp;
826
827	if (copy_from_user(&tmp, tchars, sizeof(tmp)))
828		return -EFAULT;
829	mutex_lock(&tty->termios_mutex);
830	tty->termios->c_cc[VINTR] = tmp.t_intrc;
831	tty->termios->c_cc[VQUIT] = tmp.t_quitc;
832	tty->termios->c_cc[VSTART] = tmp.t_startc;
833	tty->termios->c_cc[VSTOP] = tmp.t_stopc;
834	tty->termios->c_cc[VEOF] = tmp.t_eofc;
835	tty->termios->c_cc[VEOL2] = tmp.t_brkc;	/* what is brkc anyway? */
836	mutex_unlock(&tty->termios_mutex);
837	return 0;
838}
839#endif
840
841#ifdef TIOCGLTC
842static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
843{
844	struct ltchars tmp;
845
846	mutex_lock(&tty->termios_mutex);
847	tmp.t_suspc = tty->termios->c_cc[VSUSP];
848	/* what is dsuspc anyway? */
849	tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
850	tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
851	/* what is flushc anyway? */
852	tmp.t_flushc = tty->termios->c_cc[VEOL2];
853	tmp.t_werasc = tty->termios->c_cc[VWERASE];
854	tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
855	mutex_unlock(&tty->termios_mutex);
856	return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
857}
858
859static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
860{
861	struct ltchars tmp;
862
863	if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
864		return -EFAULT;
865
866	mutex_lock(&tty->termios_mutex);
867	tty->termios->c_cc[VSUSP] = tmp.t_suspc;
868	/* what is dsuspc anyway? */
869	tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
870	tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
871	/* what is flushc anyway? */
872	tty->termios->c_cc[VEOL2] = tmp.t_flushc;
873	tty->termios->c_cc[VWERASE] = tmp.t_werasc;
874	tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
875	mutex_unlock(&tty->termios_mutex);
876	return 0;
877}
878#endif
879
880/**
881 *	send_prio_char		-	send priority character
882 *
883 *	Send a high priority character to the tty even if stopped
884 *
885 *	Locking: none for xchar method, write ordering for write method.
886 */
887
888static int send_prio_char(struct tty_struct *tty, char ch)
889{
890	int	was_stopped = tty->stopped;
891
892	if (tty->ops->send_xchar) {
893		tty->ops->send_xchar(tty, ch);
894		return 0;
895	}
896
897	if (tty_write_lock(tty, 0) < 0)
898		return -ERESTARTSYS;
899
900	if (was_stopped)
901		start_tty(tty);
902	tty->ops->write(tty, &ch, 1);
903	if (was_stopped)
904		stop_tty(tty);
905	tty_write_unlock(tty);
906	return 0;
907}
908
909/**
910 *	tty_change_softcar	-	carrier change ioctl helper
911 *	@tty: tty to update
912 *	@arg: enable/disable CLOCAL
913 *
914 *	Perform a change to the CLOCAL state and call into the driver
915 *	layer to make it visible. All done with the termios mutex
916 */
917
918static int tty_change_softcar(struct tty_struct *tty, int arg)
919{
920	int ret = 0;
921	int bit = arg ? CLOCAL : 0;
922	struct ktermios old;
923
924	mutex_lock(&tty->termios_mutex);
925	old = *tty->termios;
926	tty->termios->c_cflag &= ~CLOCAL;
927	tty->termios->c_cflag |= bit;
928	if (tty->ops->set_termios)
929		tty->ops->set_termios(tty, &old);
930	if ((tty->termios->c_cflag & CLOCAL) != bit)
931		ret = -EINVAL;
932	mutex_unlock(&tty->termios_mutex);
933	return ret;
934}
935
936/**
937 *	tty_mode_ioctl		-	mode related ioctls
938 *	@tty: tty for the ioctl
939 *	@file: file pointer for the tty
940 *	@cmd: command
941 *	@arg: ioctl argument
942 *
943 *	Perform non line discipline specific mode control ioctls. This
944 *	is designed to be called by line disciplines to ensure they provide
945 *	consistent mode setting.
946 */
947
948int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
949			unsigned int cmd, unsigned long arg)
950{
951	struct tty_struct *real_tty;
952	void __user *p = (void __user *)arg;
953	int ret = 0;
954	struct ktermios kterm;
955
956	BUG_ON(file == NULL);
957
958	if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
959	    tty->driver->subtype == PTY_TYPE_MASTER)
960		real_tty = tty->link;
961	else
962		real_tty = tty;
963
964	switch (cmd) {
965#ifdef TIOCGETP
966	case TIOCGETP:
967		return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
968	case TIOCSETP:
969	case TIOCSETN:
970		return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
971#endif
972#ifdef TIOCGETC
973	case TIOCGETC:
974		return get_tchars(real_tty, p);
975	case TIOCSETC:
976		return set_tchars(real_tty, p);
977#endif
978#ifdef TIOCGLTC
979	case TIOCGLTC:
980		return get_ltchars(real_tty, p);
981	case TIOCSLTC:
982		return set_ltchars(real_tty, p);
983#endif
984	case TCSETSF:
985		return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
986	case TCSETSW:
987		return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
988	case TCSETS:
989		return set_termios(real_tty, p, TERMIOS_OLD);
990#ifndef TCGETS2
991	case TCGETS:
992		copy_termios(real_tty, &kterm);
993		if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
994			ret = -EFAULT;
995		return ret;
996#else
997	case TCGETS:
998		copy_termios(real_tty, &kterm);
999		if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
1000			ret = -EFAULT;
1001		return ret;
1002	case TCGETS2:
1003		copy_termios(real_tty, &kterm);
1004		if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm))
1005			ret = -EFAULT;
1006		return ret;
1007	case TCSETSF2:
1008		return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT);
1009	case TCSETSW2:
1010		return set_termios(real_tty, p, TERMIOS_WAIT);
1011	case TCSETS2:
1012		return set_termios(real_tty, p, 0);
1013#endif
1014	case TCGETA:
1015		return get_termio(real_tty, p);
1016	case TCSETAF:
1017		return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
1018	case TCSETAW:
1019		return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
1020	case TCSETA:
1021		return set_termios(real_tty, p, TERMIOS_TERMIO);
1022#ifndef TCGETS2
1023	case TIOCGLCKTRMIOS:
1024		copy_termios_locked(real_tty, &kterm);
1025		if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
1026			ret = -EFAULT;
1027		return ret;
1028	case TIOCSLCKTRMIOS:
1029		if (!capable(CAP_SYS_ADMIN))
1030			return -EPERM;
1031		copy_termios_locked(real_tty, &kterm);
1032		if (user_termios_to_kernel_termios(&kterm,
1033					       (struct termios __user *) arg))
1034			return -EFAULT;
1035		mutex_lock(&real_tty->termios_mutex);
1036		memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
1037		mutex_unlock(&real_tty->termios_mutex);
1038		return 0;
1039#else
1040	case TIOCGLCKTRMIOS:
1041		copy_termios_locked(real_tty, &kterm);
1042		if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
1043			ret = -EFAULT;
1044		return ret;
1045	case TIOCSLCKTRMIOS:
1046		if (!capable(CAP_SYS_ADMIN))
1047			return -EPERM;
1048		copy_termios_locked(real_tty, &kterm);
1049		if (user_termios_to_kernel_termios_1(&kterm,
1050					       (struct termios __user *) arg))
1051			return -EFAULT;
1052		mutex_lock(&real_tty->termios_mutex);
1053		memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
1054		mutex_unlock(&real_tty->termios_mutex);
1055		return ret;
1056#endif
1057#ifdef TCGETX
1058	case TCGETX: {
1059		struct termiox ktermx;
1060		if (real_tty->termiox == NULL)
1061			return -EINVAL;
1062		mutex_lock(&real_tty->termios_mutex);
1063		memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox));
1064		mutex_unlock(&real_tty->termios_mutex);
1065		if (copy_to_user(p, &ktermx, sizeof(struct termiox)))
1066			ret = -EFAULT;
1067		return ret;
1068	}
1069	case TCSETX:
1070		return set_termiox(real_tty, p, 0);
1071	case TCSETXW:
1072		return set_termiox(real_tty, p, TERMIOS_WAIT);
1073	case TCSETXF:
1074		return set_termiox(real_tty, p, TERMIOS_FLUSH);
1075#endif
1076	case TIOCGSOFTCAR:
1077		copy_termios(real_tty, &kterm);
1078		ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0,
1079						(int __user *)arg);
1080		return ret;
1081	case TIOCSSOFTCAR:
1082		if (get_user(arg, (unsigned int __user *) arg))
1083			return -EFAULT;
1084		return tty_change_softcar(real_tty, arg);
1085	default:
1086		return -ENOIOCTLCMD;
1087	}
1088}
1089EXPORT_SYMBOL_GPL(tty_mode_ioctl);
1090
1091int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
1092{
1093	struct tty_ldisc *ld;
1094	int retval = tty_check_change(tty);
1095	if (retval)
1096		return retval;
1097
1098	ld = tty_ldisc_ref_wait(tty);
1099	switch (arg) {
1100	case TCIFLUSH:
1101		if (ld && ld->ops->flush_buffer)
1102			ld->ops->flush_buffer(tty);
1103		break;
1104	case TCIOFLUSH:
1105		if (ld && ld->ops->flush_buffer)
1106			ld->ops->flush_buffer(tty);
1107		/* fall through */
1108	case TCOFLUSH:
1109		tty_driver_flush_buffer(tty);
1110		break;
1111	default:
1112		tty_ldisc_deref(ld);
1113		return -EINVAL;
1114	}
1115	tty_ldisc_deref(ld);
1116	return 0;
1117}
1118EXPORT_SYMBOL_GPL(tty_perform_flush);
1119
1120int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
1121		       unsigned int cmd, unsigned long arg)
1122{
1123	unsigned long flags;
1124	int retval;
1125
1126	switch (cmd) {
1127	case TCXONC:
1128		retval = tty_check_change(tty);
1129		if (retval)
1130			return retval;
1131		switch (arg) {
1132		case TCOOFF:
1133			if (!tty->flow_stopped) {
1134				tty->flow_stopped = 1;
1135				stop_tty(tty);
1136			}
1137			break;
1138		case TCOON:
1139			if (tty->flow_stopped) {
1140				tty->flow_stopped = 0;
1141				start_tty(tty);
1142			}
1143			break;
1144		case TCIOFF:
1145			if (STOP_CHAR(tty) != __DISABLED_CHAR)
1146				return send_prio_char(tty, STOP_CHAR(tty));
1147			break;
1148		case TCION:
1149			if (START_CHAR(tty) != __DISABLED_CHAR)
1150				return send_prio_char(tty, START_CHAR(tty));
1151			break;
1152		default:
1153			return -EINVAL;
1154		}
1155		return 0;
1156	case TCFLSH:
1157		return tty_perform_flush(tty, arg);
1158	case TIOCPKT:
1159	{
1160		int pktmode;
1161
1162		if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
1163		    tty->driver->subtype != PTY_TYPE_MASTER)
1164			return -ENOTTY;
1165		if (get_user(pktmode, (int __user *) arg))
1166			return -EFAULT;
1167		spin_lock_irqsave(&tty->ctrl_lock, flags);
1168		if (pktmode) {
1169			if (!tty->packet) {
1170				tty->packet = 1;
1171				tty->link->ctrl_status = 0;
1172			}
1173		} else
1174			tty->packet = 0;
1175		spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1176		return 0;
1177	}
1178	default:
1179		/* Try the mode commands */
1180		return tty_mode_ioctl(tty, file, cmd, arg);
1181	}
1182}
1183EXPORT_SYMBOL(n_tty_ioctl_helper);
1184