2 * linux/drivers/char/tty_ioctl.c
4 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
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).
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>
21 #include <linux/module.h>
22 #include <linux/bitops.h>
23 #include <linux/mutex.h>
26 #include <asm/uaccess.h>
27 #include <asm/system.h>
29 #undef TTY_DEBUG_WAIT_UNTIL_SENT
34 * Internal flag options for termios setting behavior
36 #define TERMIOS_FLUSH 1
37 #define TERMIOS_WAIT 2
38 #define TERMIOS_TERMIO 4
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
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)
53 void tty_wait_until_sent(struct tty_struct *tty, long timeout)
55 #ifdef TTY_DEBUG_WAIT_UNTIL_SENT
58 printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
60 if (!tty->driver->chars_in_buffer)
63 timeout = MAX_SCHEDULE_TIMEOUT;
64 if (wait_event_interruptible_timeout(tty->write_wait,
65 !tty->driver->chars_in_buffer(tty), timeout) < 0)
67 if (tty->driver->wait_until_sent)
68 tty->driver->wait_until_sent(tty, timeout);
70 EXPORT_SYMBOL(tty_wait_until_sent);
72 static void unset_locked_termios(struct ktermios *termios,
74 struct ktermios *locked)
78 #define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
81 printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
85 NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
86 NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
87 NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
88 NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
89 termios->c_line = locked->c_line ? old->c_line : termios->c_line;
90 for (i = 0; i < NCCS; i++)
91 termios->c_cc[i] = locked->c_cc[i] ?
92 old->c_cc[i] : termios->c_cc[i];
93 /* FIXME: What should we do for i/ospeed */
97 * Routine which returns the baud rate of the tty
99 * Note that the baud_table needs to be kept in sync with the
100 * include/asm/termbits.h file.
102 static const speed_t baud_table[] = {
103 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
104 9600, 19200, 38400, 57600, 115200, 230400, 460800,
106 76800, 153600, 307200, 614400, 921600
108 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
109 2500000, 3000000, 3500000, 4000000
114 static const tcflag_t baud_bits[] = {
115 B0, B50, B75, B110, B134, B150, B200, B300, B600,
116 B1200, B1800, B2400, B4800, B9600, B19200, B38400,
117 B57600, B115200, B230400, B460800, B500000, B576000,
118 B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
119 B3000000, B3500000, B4000000
122 static const tcflag_t baud_bits[] = {
123 B0, B50, B75, B110, B134, B150, B200, B300, B600,
124 B1200, B1800, B2400, B4800, B9600, B19200, B38400,
125 B57600, B115200, B230400, B460800, B76800, B153600,
126 B307200, B614400, B921600
130 static int n_baud_table = ARRAY_SIZE(baud_table);
133 * tty_termios_baud_rate
134 * @termios: termios structure
136 * Convert termios baud rate data into a speed. This should be called
137 * with the termios lock held if this termios is a terminal termios
138 * structure. May change the termios data. Device drivers can call this
139 * function but should use ->c_[io]speed directly as they are updated.
144 speed_t tty_termios_baud_rate(struct ktermios *termios)
148 cbaud = termios->c_cflag & CBAUD;
151 /* Magic token for arbitary speed via c_ispeed/c_ospeed */
153 return termios->c_ospeed;
155 if (cbaud & CBAUDEX) {
158 if (cbaud < 1 || cbaud + 15 > n_baud_table)
159 termios->c_cflag &= ~CBAUDEX;
163 return baud_table[cbaud];
165 EXPORT_SYMBOL(tty_termios_baud_rate);
168 * tty_termios_input_baud_rate
169 * @termios: termios structure
171 * Convert termios baud rate data into a speed. This should be called
172 * with the termios lock held if this termios is a terminal termios
173 * structure. May change the termios data. Device drivers can call this
174 * function but should use ->c_[io]speed directly as they are updated.
179 speed_t tty_termios_input_baud_rate(struct ktermios *termios)
182 unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
185 return tty_termios_baud_rate(termios);
187 /* Magic token for arbitary speed via c_ispeed*/
189 return termios->c_ispeed;
191 if (cbaud & CBAUDEX) {
194 if (cbaud < 1 || cbaud + 15 > n_baud_table)
195 termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
199 return baud_table[cbaud];
201 return tty_termios_baud_rate(termios);
204 EXPORT_SYMBOL(tty_termios_input_baud_rate);
207 * tty_termios_encode_baud_rate
208 * @termios: ktermios structure holding user requested state
209 * @ispeed: input speed
210 * @ospeed: output speed
212 * Encode the speeds set into the passed termios structure. This is
213 * used as a library helper for drivers os that they can report back
214 * the actual speed selected when it differs from the speed requested
216 * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
217 * we need to carefully set the bits when the user does not get the
218 * desired speed. We allow small margins and preserve as much of possible
219 * of the input intent to keep compatiblity.
221 * Locking: Caller should hold termios lock. This is already held
222 * when calling this function from the driver termios handler.
224 * The ifdefs deal with platforms whose owners have yet to update them
225 * and will all go away once this is done.
228 void tty_termios_encode_baud_rate(struct ktermios *termios,
229 speed_t ibaud, speed_t obaud)
232 int ifound = -1, ofound = -1;
233 int iclose = ibaud/50, oclose = obaud/50;
236 if (obaud == 0) /* CD dropped */
237 ibaud = 0; /* Clear ibaud to be sure */
239 termios->c_ispeed = ibaud;
240 termios->c_ospeed = obaud;
243 /* If the user asked for a precise weird speed give a precise weird
244 answer. If they asked for a Bfoo speed they many have problems
245 digesting non-exact replies so fuzz a bit */
247 if ((termios->c_cflag & CBAUD) == BOTHER)
249 if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER)
251 if ((termios->c_cflag >> IBSHIFT) & CBAUD)
252 ibinput = 1; /* An input speed was specified */
254 termios->c_cflag &= ~CBAUD;
257 * Our goal is to find a close match to the standard baud rate
258 * returned. Walk the baud rate table and if we get a very close
259 * match then report back the speed as a POSIX Bxxxx value by
264 if (obaud - oclose <= baud_table[i] &&
265 obaud + oclose >= baud_table[i]) {
266 termios->c_cflag |= baud_bits[i];
269 if (ibaud - iclose <= baud_table[i] &&
270 ibaud + iclose >= baud_table[i]) {
271 /* For the case input == output don't set IBAUD bits
272 if the user didn't do so */
273 if (ofound == i && !ibinput)
278 termios->c_cflag |= (baud_bits[i] << IBSHIFT);
282 } while (++i < n_baud_table);
285 * If we found no match then use BOTHER if provided or warn
286 * the user their platform maintainer needs to wake up if not.
290 termios->c_cflag |= BOTHER;
291 /* Set exact input bits only if the input and output differ or the
293 if (ifound == -1 && (ibaud != obaud || ibinput))
294 termios->c_cflag |= (BOTHER << IBSHIFT);
296 if (ifound == -1 || ofound == -1) {
299 printk(KERN_WARNING "tty: Unable to return correct "
300 "speed data as your architecture needs updating.\n");
304 EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
306 void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
308 tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
310 EXPORT_SYMBOL_GPL(tty_encode_baud_rate);
313 * tty_get_baud_rate - get tty bit rates
316 * Returns the baud rate as an integer for this terminal. The
317 * termios lock must be held by the caller and the terminal bit
318 * flags may be updated.
323 speed_t tty_get_baud_rate(struct tty_struct *tty)
325 speed_t baud = tty_termios_baud_rate(tty->termios);
327 if (baud == 38400 && tty->alt_speed) {
329 printk(KERN_WARNING "Use of setserial/setrocket to "
330 "set SPD_* flags is deprecated\n");
333 baud = tty->alt_speed;
338 EXPORT_SYMBOL(tty_get_baud_rate);
341 * tty_termios_copy_hw - copy hardware settings
345 * Propogate the hardware specific terminal setting bits from
346 * the old termios structure to the new one. This is used in cases
347 * where the hardware does not support reconfiguration or as a helper
348 * in some cases where only minimal reconfiguration is supported
351 void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old)
353 /* The bits a dumb device handles in software. Smart devices need
354 to always provide a set_termios method */
355 new->c_cflag &= HUPCL | CREAD | CLOCAL;
356 new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL);
357 new->c_ispeed = old->c_ispeed;
358 new->c_ospeed = old->c_ospeed;
360 EXPORT_SYMBOL(tty_termios_copy_hw);
363 * tty_termios_hw_change - check for setting change
365 * @b: termios to compare
367 * Check if any of the bits that affect a dumb device have changed
368 * between the two termios structures, or a speed change is needed.
371 int tty_termios_hw_change(struct ktermios *a, struct ktermios *b)
373 if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
375 if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL))
379 EXPORT_SYMBOL(tty_termios_hw_change);
382 * change_termios - update termios values
383 * @tty: tty to update
384 * @new_termios: desired new value
386 * Perform updates to the termios values set on this terminal. There
387 * is a bit of layering violation here with n_tty in terms of the
388 * internal knowledge of this function.
390 * Locking: termios_sem
393 static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
396 struct ktermios old_termios = *tty->termios;
397 struct tty_ldisc *ld;
401 * Perform the actual termios internal changes under lock.
405 /* FIXME: we need to decide on some locking/ordering semantics
406 for the set_termios notification eventually */
407 mutex_lock(&tty->termios_mutex);
409 *tty->termios = *new_termios;
410 unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
411 canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
413 memset(&tty->read_flags, 0, sizeof tty->read_flags);
414 tty->canon_head = tty->read_tail;
419 /* This bit should be in the ldisc code */
420 if (canon_change && !L_ICANON(tty) && tty->read_cnt)
421 /* Get characters left over from canonical mode. */
422 wake_up_interruptible(&tty->read_wait);
424 /* See if packet mode change of state. */
425 if (tty->link && tty->link->packet) {
426 int old_flow = ((old_termios.c_iflag & IXON) &&
427 (old_termios.c_cc[VSTOP] == '\023') &&
428 (old_termios.c_cc[VSTART] == '\021'));
429 int new_flow = (I_IXON(tty) &&
430 STOP_CHAR(tty) == '\023' &&
431 START_CHAR(tty) == '\021');
432 if (old_flow != new_flow) {
433 spin_lock_irqsave(&tty->ctrl_lock, flags);
434 tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
436 tty->ctrl_status |= TIOCPKT_DOSTOP;
438 tty->ctrl_status |= TIOCPKT_NOSTOP;
439 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
440 wake_up_interruptible(&tty->link->read_wait);
444 if (tty->driver->set_termios)
445 (*tty->driver->set_termios)(tty, &old_termios);
447 tty_termios_copy_hw(tty->termios, &old_termios);
449 ld = tty_ldisc_ref(tty);
452 (ld->set_termios)(tty, &old_termios);
455 mutex_unlock(&tty->termios_mutex);
459 * set_termios - set termios values for a tty
460 * @tty: terminal device
462 * @opt: option information
464 * Helper function to prepare termios data and run necessary other
465 * functions before using change_termios to do the actual changes.
468 * Called functions take ldisc and termios_sem locks
471 static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
473 struct ktermios tmp_termios;
474 struct tty_ldisc *ld;
475 int retval = tty_check_change(tty);
480 memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
482 if (opt & TERMIOS_TERMIO) {
483 if (user_termio_to_kernel_termios(&tmp_termios,
484 (struct termio __user *)arg))
487 } else if (opt & TERMIOS_OLD) {
488 if (user_termios_to_kernel_termios_1(&tmp_termios,
489 (struct termios __user *)arg))
492 if (user_termios_to_kernel_termios(&tmp_termios,
493 (struct termios2 __user *)arg))
497 } else if (user_termios_to_kernel_termios(&tmp_termios,
498 (struct termios __user *)arg))
502 /* If old style Bfoo values are used then load c_ispeed/c_ospeed
503 * with the real speed so its unconditionally usable */
504 tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
505 tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
507 ld = tty_ldisc_ref(tty);
510 if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
511 ld->flush_buffer(tty);
515 if (opt & TERMIOS_WAIT) {
516 tty_wait_until_sent(tty, 0);
517 if (signal_pending(current))
521 change_termios(tty, &tmp_termios);
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
530 static int get_termio(struct tty_struct *tty, struct termio __user *termio)
532 if (kernel_termios_to_user_termio(termio, tty->termios))
537 static unsigned long inq_canon(struct tty_struct *tty)
541 if (!tty->canon_data || !tty->read_buf)
543 head = tty->canon_head;
544 tail = tty->read_tail;
545 nr = (head - tail) & (N_TTY_BUF_SIZE-1);
546 /* Skip EOF-chars.. */
547 while (head != tail) {
548 if (test_bit(tail, tty->read_flags) &&
549 tty->read_buf[tail] == __DISABLED_CHAR)
551 tail = (tail+1) & (N_TTY_BUF_SIZE-1);
558 * These are deprecated, but there is limited support..
560 * The "sg_flags" translation is a joke..
562 static int get_sgflags(struct tty_struct *tty)
566 if (!(tty->termios->c_lflag & ICANON)) {
567 if (tty->termios->c_lflag & ISIG)
568 flags |= 0x02; /* cbreak */
570 flags |= 0x20; /* raw */
572 if (tty->termios->c_lflag & ECHO)
573 flags |= 0x08; /* echo */
574 if (tty->termios->c_oflag & OPOST)
575 if (tty->termios->c_oflag & ONLCR)
576 flags |= 0x10; /* crmod */
580 static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
584 mutex_lock(&tty->termios_mutex);
585 tmp.sg_ispeed = tty->termios->c_ispeed;
586 tmp.sg_ospeed = tty->termios->c_ospeed;
587 tmp.sg_erase = tty->termios->c_cc[VERASE];
588 tmp.sg_kill = tty->termios->c_cc[VKILL];
589 tmp.sg_flags = get_sgflags(tty);
590 mutex_unlock(&tty->termios_mutex);
592 return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
595 static void set_sgflags(struct ktermios *termios, int flags)
597 termios->c_iflag = ICRNL | IXON;
598 termios->c_oflag = 0;
599 termios->c_lflag = ISIG | ICANON;
600 if (flags & 0x02) { /* cbreak */
601 termios->c_iflag = 0;
602 termios->c_lflag &= ~ICANON;
604 if (flags & 0x08) { /* echo */
605 termios->c_lflag |= ECHO | ECHOE | ECHOK |
606 ECHOCTL | ECHOKE | IEXTEN;
608 if (flags & 0x10) { /* crmod */
609 termios->c_oflag |= OPOST | ONLCR;
611 if (flags & 0x20) { /* raw */
612 termios->c_iflag = 0;
613 termios->c_lflag &= ~(ISIG | ICANON);
615 if (!(termios->c_lflag & ICANON)) {
616 termios->c_cc[VMIN] = 1;
617 termios->c_cc[VTIME] = 0;
622 * set_sgttyb - set legacy terminal values
623 * @tty: tty structure
624 * @sgttyb: pointer to old style terminal structure
626 * Updates a terminal from the legacy BSD style terminal information
629 * Locking: termios_sem
632 static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
636 struct ktermios termios;
638 retval = tty_check_change(tty);
642 if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
645 mutex_lock(&tty->termios_mutex);
646 termios = *tty->termios;
647 termios.c_cc[VERASE] = tmp.sg_erase;
648 termios.c_cc[VKILL] = tmp.sg_kill;
649 set_sgflags(&termios, tmp.sg_flags);
650 /* Try and encode into Bfoo format */
652 tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
655 mutex_unlock(&tty->termios_mutex);
656 change_termios(tty, &termios);
662 static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
666 tmp.t_intrc = tty->termios->c_cc[VINTR];
667 tmp.t_quitc = tty->termios->c_cc[VQUIT];
668 tmp.t_startc = tty->termios->c_cc[VSTART];
669 tmp.t_stopc = tty->termios->c_cc[VSTOP];
670 tmp.t_eofc = tty->termios->c_cc[VEOF];
671 tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
672 return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
675 static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
679 if (copy_from_user(&tmp, tchars, sizeof(tmp)))
681 tty->termios->c_cc[VINTR] = tmp.t_intrc;
682 tty->termios->c_cc[VQUIT] = tmp.t_quitc;
683 tty->termios->c_cc[VSTART] = tmp.t_startc;
684 tty->termios->c_cc[VSTOP] = tmp.t_stopc;
685 tty->termios->c_cc[VEOF] = tmp.t_eofc;
686 tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
692 static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
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 return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
707 static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
711 if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
714 tty->termios->c_cc[VSUSP] = tmp.t_suspc;
715 /* what is dsuspc anyway? */
716 tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
717 tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
718 /* what is flushc anyway? */
719 tty->termios->c_cc[VEOL2] = tmp.t_flushc;
720 tty->termios->c_cc[VWERASE] = tmp.t_werasc;
721 tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
727 * send_prio_char - send priority character
729 * Send a high priority character to the tty even if stopped
731 * Locking: none for xchar method, write ordering for write method.
734 static int send_prio_char(struct tty_struct *tty, char ch)
736 int was_stopped = tty->stopped;
738 if (tty->driver->send_xchar) {
739 tty->driver->send_xchar(tty, ch);
743 if (tty_write_lock(tty, 0) < 0)
748 tty->driver->write(tty, &ch, 1);
751 tty_write_unlock(tty);
756 * tty_mode_ioctl - mode related ioctls
757 * @tty: tty for the ioctl
758 * @file: file pointer for the tty
760 * @arg: ioctl argument
762 * Perform non line discipline specific mode control ioctls. This
763 * is designed to be called by line disciplines to ensure they provide
764 * consistent mode setting.
767 int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
768 unsigned int cmd, unsigned long arg)
770 struct tty_struct *real_tty;
771 void __user *p = (void __user *)arg;
773 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
774 tty->driver->subtype == PTY_TYPE_MASTER)
775 real_tty = tty->link;
782 return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
785 return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
789 return get_tchars(real_tty, p);
791 return set_tchars(real_tty, p);
795 return get_ltchars(real_tty, p);
797 return set_ltchars(real_tty, p);
800 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
802 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
804 return set_termios(real_tty, p, TERMIOS_OLD);
807 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
812 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios))
816 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios))
820 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT);
822 return set_termios(real_tty, p, TERMIOS_WAIT);
824 return set_termios(real_tty, p, 0);
827 return get_termio(real_tty, p);
829 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
831 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
833 return set_termios(real_tty, p, TERMIOS_TERMIO);
836 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
840 if (!capable(CAP_SYS_ADMIN))
842 if (user_termios_to_kernel_termios(real_tty->termios_locked,
843 (struct termios __user *) arg))
848 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
852 if (!capable(CAP_SYS_ADMIN))
854 if (user_termios_to_kernel_termios_1(real_tty->termios_locked,
855 (struct termios __user *) arg))
860 return put_user(C_CLOCAL(tty) ? 1 : 0,
863 if (get_user(arg, (unsigned int __user *) arg))
865 mutex_lock(&tty->termios_mutex);
866 tty->termios->c_cflag =
867 ((tty->termios->c_cflag & ~CLOCAL) |
869 mutex_unlock(&tty->termios_mutex);
875 EXPORT_SYMBOL_GPL(tty_mode_ioctl);
877 int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
879 struct tty_ldisc *ld;
880 int retval = tty_check_change(tty);
884 ld = tty_ldisc_ref(tty);
887 if (ld && ld->flush_buffer)
888 ld->flush_buffer(tty);
891 if (ld && ld->flush_buffer)
892 ld->flush_buffer(tty);
895 if (tty->driver->flush_buffer)
896 tty->driver->flush_buffer(tty);
905 EXPORT_SYMBOL_GPL(tty_perform_flush);
907 int n_tty_ioctl(struct tty_struct *tty, struct file *file,
908 unsigned int cmd, unsigned long arg)
910 struct tty_struct *real_tty;
914 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
915 tty->driver->subtype == PTY_TYPE_MASTER)
916 real_tty = tty->link;
922 retval = tty_check_change(tty);
927 if (!tty->flow_stopped) {
928 tty->flow_stopped = 1;
933 if (tty->flow_stopped) {
934 tty->flow_stopped = 0;
939 if (STOP_CHAR(tty) != __DISABLED_CHAR)
940 return send_prio_char(tty, STOP_CHAR(tty));
943 if (START_CHAR(tty) != __DISABLED_CHAR)
944 return send_prio_char(tty, START_CHAR(tty));
951 return tty_perform_flush(tty, arg);
953 return put_user(tty->driver->chars_in_buffer ?
954 tty->driver->chars_in_buffer(tty) : 0,
957 retval = tty->read_cnt;
959 retval = inq_canon(tty);
960 return put_user(retval, (unsigned int __user *) arg);
965 if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
966 tty->driver->subtype != PTY_TYPE_MASTER)
968 if (get_user(pktmode, (int __user *) arg))
970 spin_lock_irqsave(&tty->ctrl_lock, flags);
974 tty->link->ctrl_status = 0;
978 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
982 /* Try the mode commands */
983 return tty_mode_ioctl(tty, file, cmd, arg);
986 EXPORT_SYMBOL(n_tty_ioctl);