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_wait_until_sent	-	wait for I/O to finish
44 *	@tty: tty we are waiting for
45 *	@timeout: how long we will wait
46 *
47 *	Wait for characters pending in a tty driver to hit the wire, or
48 *	for a timeout to occur (eg due to flow control)
49 *
50 *	Locking: none
51 */
52
53void tty_wait_until_sent(struct tty_struct * tty, long timeout)
54{
55	DECLARE_WAITQUEUE(wait, current);
56
57#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
58	char buf[64];
59
60	printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
61#endif
62	if (!tty->driver->chars_in_buffer)
63		return;
64	add_wait_queue(&tty->write_wait, &wait);
65	if (!timeout)
66		timeout = MAX_SCHEDULE_TIMEOUT;
67	do {
68#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
69		printk(KERN_DEBUG "waiting %s...(%d)\n", tty_name(tty, buf),
70		       tty->driver->chars_in_buffer(tty));
71#endif
72		set_current_state(TASK_INTERRUPTIBLE);
73		if (signal_pending(current))
74			goto stop_waiting;
75		if (!tty->driver->chars_in_buffer(tty))
76			break;
77		timeout = schedule_timeout(timeout);
78	} while (timeout);
79	if (tty->driver->wait_until_sent)
80		tty->driver->wait_until_sent(tty, timeout);
81stop_waiting:
82	set_current_state(TASK_RUNNING);
83	remove_wait_queue(&tty->write_wait, &wait);
84}
85
86EXPORT_SYMBOL(tty_wait_until_sent);
87
88static void unset_locked_termios(struct ktermios *termios,
89				 struct ktermios *old,
90				 struct ktermios *locked)
91{
92	int	i;
93
94#define NOSET_MASK(x,y,z) (x = ((x) & ~(z)) | ((y) & (z)))
95
96	if (!locked) {
97		printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
98		return;
99	}
100
101	NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
102	NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
103	NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
104	NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
105	termios->c_line = locked->c_line ? old->c_line : termios->c_line;
106	for (i=0; i < NCCS; i++)
107		termios->c_cc[i] = locked->c_cc[i] ?
108			old->c_cc[i] : termios->c_cc[i];
109}
110
111/*
112 * Routine which returns the baud rate of the tty
113 *
114 * Note that the baud_table needs to be kept in sync with the
115 * include/asm/termbits.h file.
116 */
117static const speed_t baud_table[] = {
118	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
119	9600, 19200, 38400, 57600, 115200, 230400, 460800,
120#ifdef __sparc__
121	76800, 153600, 307200, 614400, 921600
122#else
123	500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
124	2500000, 3000000, 3500000, 4000000
125#endif
126};
127
128#ifndef __sparc__
129static const tcflag_t baud_bits[] = {
130	B0, B50, B75, B110, B134, B150, B200, B300, B600,
131	B1200, B1800, B2400, B4800, B9600, B19200, B38400,
132	B57600, B115200, B230400, B460800, B500000, B576000,
133	B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
134	B3000000, B3500000, B4000000
135};
136#else
137static const tcflag_t baud_bits[] = {
138	B0, B50, B75, B110, B134, B150, B200, B300, B600,
139	B1200, B1800, B2400, B4800, B9600, B19200, B38400,
140	B57600, B115200, B230400, B460800, B76800, B153600,
141	B307200, B614400, B921600
142};
143#endif
144
145static int n_baud_table = ARRAY_SIZE(baud_table);
146
147/**
148 *	tty_termios_baud_rate
149 *	@termios: termios structure
150 *
151 *	Convert termios baud rate data into a speed. This should be called
152 *	with the termios lock held if this termios is a terminal termios
153 *	structure. May change the termios data. Device drivers can call this
154 *	function but should use ->c_[io]speed directly as they are updated.
155 *
156 *	Locking: none
157 */
158
159speed_t tty_termios_baud_rate(struct ktermios *termios)
160{
161	unsigned int cbaud;
162
163	cbaud = termios->c_cflag & CBAUD;
164
165#ifdef BOTHER
166	/* Magic token for arbitary speed via c_ispeed/c_ospeed */
167	if (cbaud == BOTHER)
168		return termios->c_ospeed;
169#endif
170	if (cbaud & CBAUDEX) {
171		cbaud &= ~CBAUDEX;
172
173		if (cbaud < 1 || cbaud + 15 > n_baud_table)
174			termios->c_cflag &= ~CBAUDEX;
175		else
176			cbaud += 15;
177	}
178	return baud_table[cbaud];
179}
180
181EXPORT_SYMBOL(tty_termios_baud_rate);
182
183/**
184 *	tty_termios_input_baud_rate
185 *	@termios: termios structure
186 *
187 *	Convert termios baud rate data into a speed. This should be called
188 *	with the termios lock held if this termios is a terminal termios
189 *	structure. May change the termios data. Device drivers can call this
190 *	function but should use ->c_[io]speed directly as they are updated.
191 *
192 *	Locking: none
193 */
194
195speed_t tty_termios_input_baud_rate(struct ktermios *termios)
196{
197#ifdef IBSHIFT
198	unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
199
200	if (cbaud == B0)
201		return tty_termios_baud_rate(termios);
202
203	/* Magic token for arbitary speed via c_ispeed*/
204	if (cbaud == BOTHER)
205		return termios->c_ispeed;
206
207	if (cbaud & CBAUDEX) {
208		cbaud &= ~CBAUDEX;
209
210		if (cbaud < 1 || cbaud + 15 > n_baud_table)
211			termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
212		else
213			cbaud += 15;
214	}
215	return baud_table[cbaud];
216#else
217	return tty_termios_baud_rate(termios);
218#endif
219}
220
221EXPORT_SYMBOL(tty_termios_input_baud_rate);
222
223#ifdef BOTHER
224
225/**
226 *	tty_termios_encode_baud_rate
227 *	@termios: ktermios structure holding user requested state
228 *	@ispeed: input speed
229 *	@ospeed: output speed
230 *
231 *	Encode the speeds set into the passed termios structure. This is
232 *	used as a library helper for drivers os that they can report back
233 *	the actual speed selected when it differs from the speed requested
234 *
235 *	For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
236 *	we need to carefully set the bits when the user does not get the
237 *	desired speed. We allow small margins and preserve as much of possible
238 *	of the input intent to keep compatiblity.
239 *
240 *	Locking: Caller should hold termios lock. This is already held
241 *	when calling this function from the driver termios handler.
242 */
243
244void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud)
245{
246	int i = 0;
247	int ifound = -1, ofound = -1;
248	int iclose = ibaud/50, oclose = obaud/50;
249	int ibinput = 0;
250
251	termios->c_ispeed = ibaud;
252	termios->c_ospeed = obaud;
253
254	/* If the user asked for a precise weird speed give a precise weird
255	   answer. If they asked for a Bfoo speed they many have problems
256	   digesting non-exact replies so fuzz a bit */
257
258	if ((termios->c_cflag & CBAUD) == BOTHER)
259		oclose = 0;
260	if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER)
261		iclose = 0;
262	if ((termios->c_cflag >> IBSHIFT) & CBAUD)
263		ibinput = 1;	/* An input speed was specified */
264
265	termios->c_cflag &= ~CBAUD;
266
267	do {
268		if (obaud - oclose >= baud_table[i] && obaud + oclose <= baud_table[i]) {
269			termios->c_cflag |= baud_bits[i];
270			ofound = i;
271		}
272		if (ibaud - iclose >= baud_table[i] && ibaud + iclose <= baud_table[i]) {
273			/* For the case input == output don't set IBAUD bits if the user didn't do so */
274			if (ofound != i || ibinput)
275				termios->c_cflag |= (baud_bits[i] << IBSHIFT);
276			ifound = i;
277		}
278	}
279	while(++i < n_baud_table);
280	if (ofound == -1)
281		termios->c_cflag |= BOTHER;
282	/* Set exact input bits only if the input and output differ or the
283	   user already did */
284	if (ifound == -1 && (ibaud != obaud  || ibinput))
285		termios->c_cflag |= (BOTHER << IBSHIFT);
286}
287
288EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
289
290#endif
291
292/**
293 *	tty_get_baud_rate	-	get tty bit rates
294 *	@tty: tty to query
295 *
296 *	Returns the baud rate as an integer for this terminal. The
297 *	termios lock must be held by the caller and the terminal bit
298 *	flags may be updated.
299 *
300 *	Locking: none
301 */
302
303speed_t tty_get_baud_rate(struct tty_struct *tty)
304{
305	speed_t baud = tty_termios_baud_rate(tty->termios);
306
307	if (baud == 38400 && tty->alt_speed) {
308		if (!tty->warned) {
309			printk(KERN_WARNING "Use of setserial/setrocket to "
310					    "set SPD_* flags is deprecated\n");
311			tty->warned = 1;
312		}
313		baud = tty->alt_speed;
314	}
315
316	return baud;
317}
318
319EXPORT_SYMBOL(tty_get_baud_rate);
320
321/**
322 *	change_termios		-	update termios values
323 *	@tty: tty to update
324 *	@new_termios: desired new value
325 *
326 *	Perform updates to the termios values set on this terminal. There
327 *	is a bit of layering violation here with n_tty in terms of the
328 *	internal knowledge of this function.
329 *
330 *	Locking: termios_sem
331 */
332
333static void change_termios(struct tty_struct * tty, struct ktermios * new_termios)
334{
335	int canon_change;
336	struct ktermios old_termios = *tty->termios;
337	struct tty_ldisc *ld;
338
339	/*
340	 *	Perform the actual termios internal changes under lock.
341	 */
342
343
344	mutex_lock(&tty->termios_mutex);
345
346	*tty->termios = *new_termios;
347	unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
348	canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
349	if (canon_change) {
350		memset(&tty->read_flags, 0, sizeof tty->read_flags);
351		tty->canon_head = tty->read_tail;
352		tty->canon_data = 0;
353		tty->erasing = 0;
354	}
355
356
357	if (canon_change && !L_ICANON(tty) && tty->read_cnt)
358		/* Get characters left over from canonical mode. */
359		wake_up_interruptible(&tty->read_wait);
360
361	/* See if packet mode change of state. */
362
363	if (tty->link && tty->link->packet) {
364		int old_flow = ((old_termios.c_iflag & IXON) &&
365				(old_termios.c_cc[VSTOP] == '\023') &&
366				(old_termios.c_cc[VSTART] == '\021'));
367		int new_flow = (I_IXON(tty) &&
368				STOP_CHAR(tty) == '\023' &&
369				START_CHAR(tty) == '\021');
370		if (old_flow != new_flow) {
371			tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
372			if (new_flow)
373				tty->ctrl_status |= TIOCPKT_DOSTOP;
374			else
375				tty->ctrl_status |= TIOCPKT_NOSTOP;
376			wake_up_interruptible(&tty->link->read_wait);
377		}
378	}
379
380	if (tty->driver->set_termios)
381		(*tty->driver->set_termios)(tty, &old_termios);
382
383	ld = tty_ldisc_ref(tty);
384	if (ld != NULL) {
385		if (ld->set_termios)
386			(ld->set_termios)(tty, &old_termios);
387		tty_ldisc_deref(ld);
388	}
389	mutex_unlock(&tty->termios_mutex);
390}
391
392/**
393 *	set_termios		-	set termios values for a tty
394 *	@tty: terminal device
395 *	@arg: user data
396 *	@opt: option information
397 *
398 *	Helper function to prepare termios data and run neccessary other
399 *	functions before using change_termios to do the actual changes.
400 *
401 *	Locking:
402 *		Called functions take ldisc and termios_sem locks
403 */
404
405static int set_termios(struct tty_struct * tty, void __user *arg, int opt)
406{
407	struct ktermios tmp_termios;
408	struct tty_ldisc *ld;
409	int retval = tty_check_change(tty);
410
411	if (retval)
412		return retval;
413
414	memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
415
416	if (opt & TERMIOS_TERMIO) {
417		if (user_termio_to_kernel_termios(&tmp_termios,
418						(struct termio __user *)arg))
419			return -EFAULT;
420#ifdef TCGETS2
421	} else if (opt & TERMIOS_OLD) {
422		if (user_termios_to_kernel_termios_1(&tmp_termios,
423						(struct termios __user *)arg))
424			return -EFAULT;
425	} else {
426		if (user_termios_to_kernel_termios(&tmp_termios,
427						(struct termios2 __user *)arg))
428			return -EFAULT;
429	}
430#else
431	} else if (user_termios_to_kernel_termios(&tmp_termios,
432					(struct termios __user *)arg))
433		return -EFAULT;
434#endif
435
436	/* If old style Bfoo values are used then load c_ispeed/c_ospeed with the real speed
437	   so its unconditionally usable */
438	tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
439	tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
440
441	ld = tty_ldisc_ref(tty);
442
443	if (ld != NULL) {
444		if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
445			ld->flush_buffer(tty);
446		tty_ldisc_deref(ld);
447	}
448
449	if (opt & TERMIOS_WAIT) {
450		tty_wait_until_sent(tty, 0);
451		if (signal_pending(current))
452			return -EINTR;
453	}
454
455	change_termios(tty, &tmp_termios);
456	return 0;
457}
458
459static int get_termio(struct tty_struct * tty, struct termio __user * termio)
460{
461	if (kernel_termios_to_user_termio(termio, tty->termios))
462		return -EFAULT;
463	return 0;
464}
465
466static unsigned long inq_canon(struct tty_struct * tty)
467{
468	int nr, head, tail;
469
470	if (!tty->canon_data || !tty->read_buf)
471		return 0;
472	head = tty->canon_head;
473	tail = tty->read_tail;
474	nr = (head - tail) & (N_TTY_BUF_SIZE-1);
475	/* Skip EOF-chars.. */
476	while (head != tail) {
477		if (test_bit(tail, tty->read_flags) &&
478		    tty->read_buf[tail] == __DISABLED_CHAR)
479			nr--;
480		tail = (tail+1) & (N_TTY_BUF_SIZE-1);
481	}
482	return nr;
483}
484
485#ifdef TIOCGETP
486/*
487 * These are deprecated, but there is limited support..
488 *
489 * The "sg_flags" translation is a joke..
490 */
491static int get_sgflags(struct tty_struct * tty)
492{
493	int flags = 0;
494
495	if (!(tty->termios->c_lflag & ICANON)) {
496		if (tty->termios->c_lflag & ISIG)
497			flags |= 0x02;		/* cbreak */
498		else
499			flags |= 0x20;		/* raw */
500	}
501	if (tty->termios->c_lflag & ECHO)
502		flags |= 0x08;			/* echo */
503	if (tty->termios->c_oflag & OPOST)
504		if (tty->termios->c_oflag & ONLCR)
505			flags |= 0x10;		/* crmod */
506	return flags;
507}
508
509static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
510{
511	struct sgttyb tmp;
512
513	mutex_lock(&tty->termios_mutex);
514	tmp.sg_ispeed = tty->termios->c_ispeed;
515	tmp.sg_ospeed = tty->termios->c_ospeed;
516	tmp.sg_erase = tty->termios->c_cc[VERASE];
517	tmp.sg_kill = tty->termios->c_cc[VKILL];
518	tmp.sg_flags = get_sgflags(tty);
519	mutex_unlock(&tty->termios_mutex);
520
521	return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
522}
523
524static void set_sgflags(struct ktermios * termios, int flags)
525{
526	termios->c_iflag = ICRNL | IXON;
527	termios->c_oflag = 0;
528	termios->c_lflag = ISIG | ICANON;
529	if (flags & 0x02) {	/* cbreak */
530		termios->c_iflag = 0;
531		termios->c_lflag &= ~ICANON;
532	}
533	if (flags & 0x08) {		/* echo */
534		termios->c_lflag |= ECHO | ECHOE | ECHOK |
535				    ECHOCTL | ECHOKE | IEXTEN;
536	}
537	if (flags & 0x10) {		/* crmod */
538		termios->c_oflag |= OPOST | ONLCR;
539	}
540	if (flags & 0x20) {	/* raw */
541		termios->c_iflag = 0;
542		termios->c_lflag &= ~(ISIG | ICANON);
543	}
544	if (!(termios->c_lflag & ICANON)) {
545		termios->c_cc[VMIN] = 1;
546		termios->c_cc[VTIME] = 0;
547	}
548}
549
550/**
551 *	set_sgttyb		-	set legacy terminal values
552 *	@tty: tty structure
553 *	@sgttyb: pointer to old style terminal structure
554 *
555 *	Updates a terminal from the legacy BSD style terminal information
556 *	structure.
557 *
558 *	Locking: termios_sem
559 */
560
561static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
562{
563	int retval;
564	struct sgttyb tmp;
565	struct ktermios termios;
566
567	retval = tty_check_change(tty);
568	if (retval)
569		return retval;
570
571	if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
572		return -EFAULT;
573
574	mutex_lock(&tty->termios_mutex);
575	termios =  *tty->termios;
576	termios.c_cc[VERASE] = tmp.sg_erase;
577	termios.c_cc[VKILL] = tmp.sg_kill;
578	set_sgflags(&termios, tmp.sg_flags);
579	/* Try and encode into Bfoo format */
580#ifdef BOTHER
581	tty_termios_encode_baud_rate(&termios, termios.c_ispeed, termios.c_ospeed);
582#endif
583	mutex_unlock(&tty->termios_mutex);
584	change_termios(tty, &termios);
585	return 0;
586}
587#endif
588
589#ifdef TIOCGETC
590static int get_tchars(struct tty_struct * tty, struct tchars __user * tchars)
591{
592	struct tchars tmp;
593
594	tmp.t_intrc = tty->termios->c_cc[VINTR];
595	tmp.t_quitc = tty->termios->c_cc[VQUIT];
596	tmp.t_startc = tty->termios->c_cc[VSTART];
597	tmp.t_stopc = tty->termios->c_cc[VSTOP];
598	tmp.t_eofc = tty->termios->c_cc[VEOF];
599	tmp.t_brkc = tty->termios->c_cc[VEOL2];	/* what is brkc anyway? */
600	return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
601}
602
603static int set_tchars(struct tty_struct * tty, struct tchars __user * tchars)
604{
605	struct tchars tmp;
606
607	if (copy_from_user(&tmp, tchars, sizeof(tmp)))
608		return -EFAULT;
609	tty->termios->c_cc[VINTR] = tmp.t_intrc;
610	tty->termios->c_cc[VQUIT] = tmp.t_quitc;
611	tty->termios->c_cc[VSTART] = tmp.t_startc;
612	tty->termios->c_cc[VSTOP] = tmp.t_stopc;
613	tty->termios->c_cc[VEOF] = tmp.t_eofc;
614	tty->termios->c_cc[VEOL2] = tmp.t_brkc;	/* what is brkc anyway? */
615	return 0;
616}
617#endif
618
619#ifdef TIOCGLTC
620static int get_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars)
621{
622	struct ltchars tmp;
623
624	tmp.t_suspc = tty->termios->c_cc[VSUSP];
625	tmp.t_dsuspc = tty->termios->c_cc[VSUSP];	/* what is dsuspc anyway? */
626	tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
627	tmp.t_flushc = tty->termios->c_cc[VEOL2];	/* what is flushc anyway? */
628	tmp.t_werasc = tty->termios->c_cc[VWERASE];
629	tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
630	return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
631}
632
633static int set_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars)
634{
635	struct ltchars tmp;
636
637	if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
638		return -EFAULT;
639
640	tty->termios->c_cc[VSUSP] = tmp.t_suspc;
641	tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;	/* what is dsuspc anyway? */
642	tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
643	tty->termios->c_cc[VEOL2] = tmp.t_flushc;	/* what is flushc anyway? */
644	tty->termios->c_cc[VWERASE] = tmp.t_werasc;
645	tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
646	return 0;
647}
648#endif
649
650/**
651 *	send_prio_char		-	send priority character
652 *
653 *	Send a high priority character to the tty even if stopped
654 *
655 *	Locking: none for xchar method, write ordering for write method.
656 */
657
658static int send_prio_char(struct tty_struct *tty, char ch)
659{
660	int	was_stopped = tty->stopped;
661
662	if (tty->driver->send_xchar) {
663		tty->driver->send_xchar(tty, ch);
664		return 0;
665	}
666
667	if (mutex_lock_interruptible(&tty->atomic_write_lock))
668		return -ERESTARTSYS;
669
670	if (was_stopped)
671		start_tty(tty);
672	tty->driver->write(tty, &ch, 1);
673	if (was_stopped)
674		stop_tty(tty);
675	mutex_unlock(&tty->atomic_write_lock);
676	return 0;
677}
678
679int n_tty_ioctl(struct tty_struct * tty, struct file * file,
680		       unsigned int cmd, unsigned long arg)
681{
682	struct tty_struct * real_tty;
683	void __user *p = (void __user *)arg;
684	int retval;
685	struct tty_ldisc *ld;
686
687	if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
688	    tty->driver->subtype == PTY_TYPE_MASTER)
689		real_tty = tty->link;
690	else
691		real_tty = tty;
692
693	switch (cmd) {
694#ifdef TIOCGETP
695		case TIOCGETP:
696			return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
697		case TIOCSETP:
698		case TIOCSETN:
699			return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
700#endif
701#ifdef TIOCGETC
702		case TIOCGETC:
703			return get_tchars(real_tty, p);
704		case TIOCSETC:
705			return set_tchars(real_tty, p);
706#endif
707#ifdef TIOCGLTC
708		case TIOCGLTC:
709			return get_ltchars(real_tty, p);
710		case TIOCSLTC:
711			return set_ltchars(real_tty, p);
712#endif
713		case TCSETSF:
714			return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
715		case TCSETSW:
716			return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
717		case TCSETS:
718			return set_termios(real_tty, p, TERMIOS_OLD);
719#ifndef TCGETS2
720		case TCGETS:
721			if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
722				return -EFAULT;
723			return 0;
724#else
725		case TCGETS:
726			if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios))
727				return -EFAULT;
728			return 0;
729		case TCGETS2:
730			if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios))
731				return -EFAULT;
732			return 0;
733		case TCSETSF2:
734			return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT);
735		case TCSETSW2:
736			return set_termios(real_tty, p, TERMIOS_WAIT);
737		case TCSETS2:
738			return set_termios(real_tty, p, 0);
739#endif
740		case TCGETA:
741			return get_termio(real_tty, p);
742		case TCSETAF:
743			return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
744		case TCSETAW:
745			return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
746		case TCSETA:
747			return set_termios(real_tty, p, TERMIOS_TERMIO);
748		case TCXONC:
749			retval = tty_check_change(tty);
750			if (retval)
751				return retval;
752			switch (arg) {
753			case TCOOFF:
754				if (!tty->flow_stopped) {
755					tty->flow_stopped = 1;
756					stop_tty(tty);
757				}
758				break;
759			case TCOON:
760				if (tty->flow_stopped) {
761					tty->flow_stopped = 0;
762					start_tty(tty);
763				}
764				break;
765			case TCIOFF:
766				if (STOP_CHAR(tty) != __DISABLED_CHAR)
767					return send_prio_char(tty, STOP_CHAR(tty));
768				break;
769			case TCION:
770				if (START_CHAR(tty) != __DISABLED_CHAR)
771					return send_prio_char(tty, START_CHAR(tty));
772				break;
773			default:
774				return -EINVAL;
775			}
776			return 0;
777		case TCFLSH:
778			retval = tty_check_change(tty);
779			if (retval)
780				return retval;
781
782			ld = tty_ldisc_ref(tty);
783			switch (arg) {
784			case TCIFLUSH:
785				if (ld && ld->flush_buffer)
786					ld->flush_buffer(tty);
787				break;
788			case TCIOFLUSH:
789				if (ld && ld->flush_buffer)
790					ld->flush_buffer(tty);
791				/* fall through */
792			case TCOFLUSH:
793				if (tty->driver->flush_buffer)
794					tty->driver->flush_buffer(tty);
795				break;
796			default:
797				tty_ldisc_deref(ld);
798				return -EINVAL;
799			}
800			tty_ldisc_deref(ld);
801			return 0;
802		case TIOCOUTQ:
803			return put_user(tty->driver->chars_in_buffer ?
804					tty->driver->chars_in_buffer(tty) : 0,
805					(int __user *) arg);
806		case TIOCINQ:
807			retval = tty->read_cnt;
808			if (L_ICANON(tty))
809				retval = inq_canon(tty);
810			return put_user(retval, (unsigned int __user *) arg);
811		case TIOCGLCKTRMIOS:
812			if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
813				return -EFAULT;
814			return 0;
815
816		case TIOCSLCKTRMIOS:
817			if (!capable(CAP_SYS_ADMIN))
818				return -EPERM;
819			if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg))
820				return -EFAULT;
821			return 0;
822
823		case TIOCPKT:
824		{
825			int pktmode;
826
827			if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
828			    tty->driver->subtype != PTY_TYPE_MASTER)
829				return -ENOTTY;
830			if (get_user(pktmode, (int __user *) arg))
831				return -EFAULT;
832			if (pktmode) {
833				if (!tty->packet) {
834					tty->packet = 1;
835					tty->link->ctrl_status = 0;
836				}
837			} else
838				tty->packet = 0;
839			return 0;
840		}
841		case TIOCGSOFTCAR:
842			return put_user(C_CLOCAL(tty) ? 1 : 0, (int __user *)arg);
843		case TIOCSSOFTCAR:
844			if (get_user(arg, (unsigned int __user *) arg))
845				return -EFAULT;
846			mutex_lock(&tty->termios_mutex);
847			tty->termios->c_cflag =
848				((tty->termios->c_cflag & ~CLOCAL) |
849				 (arg ? CLOCAL : 0));
850			mutex_unlock(&tty->termios_mutex);
851			return 0;
852		default:
853			return -ENOIOCTLCMD;
854		}
855}
856
857EXPORT_SYMBOL(n_tty_ioctl);
858