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
);
71 EXPORT_SYMBOL(tty_wait_until_sent
);
73 static void unset_locked_termios(struct ktermios
*termios
,
75 struct ktermios
*locked
)
79 #define NOSET_MASK(x,y,z) (x = ((x) & ~(z)) | ((y) & (z)))
82 printk(KERN_WARNING
"Warning?!? termios_locked is NULL.\n");
86 NOSET_MASK(termios
->c_iflag
, old
->c_iflag
, locked
->c_iflag
);
87 NOSET_MASK(termios
->c_oflag
, old
->c_oflag
, locked
->c_oflag
);
88 NOSET_MASK(termios
->c_cflag
, old
->c_cflag
, locked
->c_cflag
);
89 NOSET_MASK(termios
->c_lflag
, old
->c_lflag
, locked
->c_lflag
);
90 termios
->c_line
= locked
->c_line
? old
->c_line
: termios
->c_line
;
91 for (i
=0; i
< NCCS
; i
++)
92 termios
->c_cc
[i
] = locked
->c_cc
[i
] ?
93 old
->c_cc
[i
] : termios
->c_cc
[i
];
94 /* FIXME: What should we do for i/ospeed */
98 * Routine which returns the baud rate of the tty
100 * Note that the baud_table needs to be kept in sync with the
101 * include/asm/termbits.h file.
103 static const speed_t baud_table
[] = {
104 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
105 9600, 19200, 38400, 57600, 115200, 230400, 460800,
107 76800, 153600, 307200, 614400, 921600
109 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
110 2500000, 3000000, 3500000, 4000000
115 static const tcflag_t baud_bits
[] = {
116 B0
, B50
, B75
, B110
, B134
, B150
, B200
, B300
, B600
,
117 B1200
, B1800
, B2400
, B4800
, B9600
, B19200
, B38400
,
118 B57600
, B115200
, B230400
, B460800
, B500000
, B576000
,
119 B921600
, B1000000
, B1152000
, B1500000
, B2000000
, B2500000
,
120 B3000000
, B3500000
, B4000000
123 static const tcflag_t baud_bits
[] = {
124 B0
, B50
, B75
, B110
, B134
, B150
, B200
, B300
, B600
,
125 B1200
, B1800
, B2400
, B4800
, B9600
, B19200
, B38400
,
126 B57600
, B115200
, B230400
, B460800
, B76800
, B153600
,
127 B307200
, B614400
, B921600
131 static int n_baud_table
= ARRAY_SIZE(baud_table
);
134 * tty_termios_baud_rate
135 * @termios: termios structure
137 * Convert termios baud rate data into a speed. This should be called
138 * with the termios lock held if this termios is a terminal termios
139 * structure. May change the termios data. Device drivers can call this
140 * function but should use ->c_[io]speed directly as they are updated.
145 speed_t
tty_termios_baud_rate(struct ktermios
*termios
)
149 cbaud
= termios
->c_cflag
& CBAUD
;
152 /* Magic token for arbitary speed via c_ispeed/c_ospeed */
154 return termios
->c_ospeed
;
156 if (cbaud
& CBAUDEX
) {
159 if (cbaud
< 1 || cbaud
+ 15 > n_baud_table
)
160 termios
->c_cflag
&= ~CBAUDEX
;
164 return baud_table
[cbaud
];
167 EXPORT_SYMBOL(tty_termios_baud_rate
);
170 * tty_termios_input_baud_rate
171 * @termios: termios structure
173 * Convert termios baud rate data into a speed. This should be called
174 * with the termios lock held if this termios is a terminal termios
175 * structure. May change the termios data. Device drivers can call this
176 * function but should use ->c_[io]speed directly as they are updated.
181 speed_t
tty_termios_input_baud_rate(struct ktermios
*termios
)
184 unsigned int cbaud
= (termios
->c_cflag
>> IBSHIFT
) & CBAUD
;
187 return tty_termios_baud_rate(termios
);
189 /* Magic token for arbitary speed via c_ispeed*/
191 return termios
->c_ispeed
;
193 if (cbaud
& CBAUDEX
) {
196 if (cbaud
< 1 || cbaud
+ 15 > n_baud_table
)
197 termios
->c_cflag
&= ~(CBAUDEX
<< IBSHIFT
);
201 return baud_table
[cbaud
];
203 return tty_termios_baud_rate(termios
);
207 EXPORT_SYMBOL(tty_termios_input_baud_rate
);
210 * tty_termios_encode_baud_rate
211 * @termios: ktermios structure holding user requested state
212 * @ispeed: input speed
213 * @ospeed: output speed
215 * Encode the speeds set into the passed termios structure. This is
216 * used as a library helper for drivers os that they can report back
217 * the actual speed selected when it differs from the speed requested
219 * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
220 * we need to carefully set the bits when the user does not get the
221 * desired speed. We allow small margins and preserve as much of possible
222 * of the input intent to keep compatiblity.
224 * Locking: Caller should hold termios lock. This is already held
225 * when calling this function from the driver termios handler.
227 * The ifdefs deal with platforms whose owners have yet to update them
228 * and will all go away once this is done.
231 void tty_termios_encode_baud_rate(struct ktermios
*termios
,
232 speed_t ibaud
, speed_t obaud
)
235 int ifound
= -1, ofound
= -1;
236 int iclose
= ibaud
/50, oclose
= obaud
/50;
239 if (obaud
== 0) /* CD dropped */
240 ibaud
= 0; /* Clear ibaud to be sure */
242 termios
->c_ispeed
= ibaud
;
243 termios
->c_ospeed
= obaud
;
246 /* If the user asked for a precise weird speed give a precise weird
247 answer. If they asked for a Bfoo speed they many have problems
248 digesting non-exact replies so fuzz a bit */
250 if ((termios
->c_cflag
& CBAUD
) == BOTHER
)
252 if (((termios
->c_cflag
>> IBSHIFT
) & CBAUD
) == BOTHER
)
254 if ((termios
->c_cflag
>> IBSHIFT
) & CBAUD
)
255 ibinput
= 1; /* An input speed was specified */
257 termios
->c_cflag
&= ~CBAUD
;
260 * Our goal is to find a close match to the standard baud rate
261 * returned. Walk the baud rate table and if we get a very close
262 * match then report back the speed as a POSIX Bxxxx value by
267 if (obaud
- oclose
<= baud_table
[i
] &&
268 obaud
+ oclose
>= baud_table
[i
]) {
269 termios
->c_cflag
|= baud_bits
[i
];
272 if (ibaud
- iclose
<= baud_table
[i
] &&
273 ibaud
+ iclose
>= baud_table
[i
]) {
274 /* For the case input == output don't set IBAUD bits
275 if the user didn't do so */
276 if (ofound
== i
&& !ibinput
)
281 termios
->c_cflag
|= (baud_bits
[i
] << IBSHIFT
);
285 } while (++i
< n_baud_table
);
288 * If we found no match then use BOTHER if provided or warn
289 * the user their platform maintainer needs to wake up if not.
293 termios
->c_cflag
|= BOTHER
;
294 /* Set exact input bits only if the input and output differ or the
296 if (ifound
== -1 && (ibaud
!= obaud
|| ibinput
))
297 termios
->c_cflag
|= (BOTHER
<< IBSHIFT
);
299 if (ifound
== -1 || ofound
== -1) {
302 printk(KERN_WARNING
"tty: Unable to return correct "
303 "speed data as your architecture needs updating.\n");
307 EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate
);
309 void tty_encode_baud_rate(struct tty_struct
*tty
, speed_t ibaud
, speed_t obaud
)
311 tty_termios_encode_baud_rate(tty
->termios
, ibaud
, obaud
);
313 EXPORT_SYMBOL_GPL(tty_encode_baud_rate
);
316 * tty_get_baud_rate - get tty bit rates
319 * Returns the baud rate as an integer for this terminal. The
320 * termios lock must be held by the caller and the terminal bit
321 * flags may be updated.
326 speed_t
tty_get_baud_rate(struct tty_struct
*tty
)
328 speed_t baud
= tty_termios_baud_rate(tty
->termios
);
330 if (baud
== 38400 && tty
->alt_speed
) {
332 printk(KERN_WARNING
"Use of setserial/setrocket to "
333 "set SPD_* flags is deprecated\n");
336 baud
= tty
->alt_speed
;
342 EXPORT_SYMBOL(tty_get_baud_rate
);
345 * tty_termios_copy_hw - copy hardware settings
349 * Propogate the hardware specific terminal setting bits from
350 * the old termios structure to the new one. This is used in cases
351 * where the hardware does not support reconfiguration or as a helper
352 * in some cases where only minimal reconfiguration is supported
355 void tty_termios_copy_hw(struct ktermios
*new, struct ktermios
*old
)
357 /* The bits a dumb device handles in software. Smart devices need
358 to always provide a set_termios method */
359 new->c_cflag
&= HUPCL
| CREAD
| CLOCAL
;
360 new->c_cflag
|= old
->c_cflag
& ~(HUPCL
| CREAD
| CLOCAL
);
361 new->c_ispeed
= old
->c_ispeed
;
362 new->c_ospeed
= old
->c_ospeed
;
365 EXPORT_SYMBOL(tty_termios_copy_hw
);
368 * tty_termios_hw_change - check for setting change
370 * @b: termios to compare
372 * Check if any of the bits that affect a dumb device have changed
373 * between the two termios structures, or a speed change is needed.
376 int tty_termios_hw_change(struct ktermios
*a
, struct ktermios
*b
)
378 if (a
->c_ispeed
!= b
->c_ispeed
|| a
->c_ospeed
!= b
->c_ospeed
)
380 if ((a
->c_cflag
^ b
->c_cflag
) & ~(HUPCL
| CREAD
| CLOCAL
))
384 EXPORT_SYMBOL(tty_termios_hw_change
);
387 * change_termios - update termios values
388 * @tty: tty to update
389 * @new_termios: desired new value
391 * Perform updates to the termios values set on this terminal. There
392 * is a bit of layering violation here with n_tty in terms of the
393 * internal knowledge of this function.
395 * Locking: termios_sem
398 static void change_termios(struct tty_struct
* tty
, struct ktermios
* new_termios
)
401 struct ktermios old_termios
= *tty
->termios
;
402 struct tty_ldisc
*ld
;
405 * Perform the actual termios internal changes under lock.
409 /* FIXME: we need to decide on some locking/ordering semantics
410 for the set_termios notification eventually */
411 mutex_lock(&tty
->termios_mutex
);
413 *tty
->termios
= *new_termios
;
414 unset_locked_termios(tty
->termios
, &old_termios
, tty
->termios_locked
);
415 canon_change
= (old_termios
.c_lflag
^ tty
->termios
->c_lflag
) & ICANON
;
417 memset(&tty
->read_flags
, 0, sizeof tty
->read_flags
);
418 tty
->canon_head
= tty
->read_tail
;
423 /* This bit should be in the ldisc code */
424 if (canon_change
&& !L_ICANON(tty
) && tty
->read_cnt
)
425 /* Get characters left over from canonical mode. */
426 wake_up_interruptible(&tty
->read_wait
);
428 /* See if packet mode change of state. */
429 if (tty
->link
&& tty
->link
->packet
) {
430 int old_flow
= ((old_termios
.c_iflag
& IXON
) &&
431 (old_termios
.c_cc
[VSTOP
] == '\023') &&
432 (old_termios
.c_cc
[VSTART
] == '\021'));
433 int new_flow
= (I_IXON(tty
) &&
434 STOP_CHAR(tty
) == '\023' &&
435 START_CHAR(tty
) == '\021');
436 if (old_flow
!= new_flow
) {
437 tty
->ctrl_status
&= ~(TIOCPKT_DOSTOP
| TIOCPKT_NOSTOP
);
439 tty
->ctrl_status
|= TIOCPKT_DOSTOP
;
441 tty
->ctrl_status
|= TIOCPKT_NOSTOP
;
442 wake_up_interruptible(&tty
->link
->read_wait
);
446 if (tty
->driver
->set_termios
)
447 (*tty
->driver
->set_termios
)(tty
, &old_termios
);
449 tty_termios_copy_hw(tty
->termios
, &old_termios
);
451 ld
= tty_ldisc_ref(tty
);
454 (ld
->set_termios
)(tty
, &old_termios
);
457 mutex_unlock(&tty
->termios_mutex
);
461 * set_termios - set termios values for a tty
462 * @tty: terminal device
464 * @opt: option information
466 * Helper function to prepare termios data and run necessary other
467 * functions before using change_termios to do the actual changes.
470 * Called functions take ldisc and termios_sem locks
473 static int set_termios(struct tty_struct
* tty
, void __user
*arg
, int opt
)
475 struct ktermios tmp_termios
;
476 struct tty_ldisc
*ld
;
477 int retval
= tty_check_change(tty
);
482 memcpy(&tmp_termios
, tty
->termios
, sizeof(struct ktermios
));
484 if (opt
& TERMIOS_TERMIO
) {
485 if (user_termio_to_kernel_termios(&tmp_termios
,
486 (struct termio __user
*)arg
))
489 } else if (opt
& TERMIOS_OLD
) {
490 if (user_termios_to_kernel_termios_1(&tmp_termios
,
491 (struct termios __user
*)arg
))
494 if (user_termios_to_kernel_termios(&tmp_termios
,
495 (struct termios2 __user
*)arg
))
499 } else if (user_termios_to_kernel_termios(&tmp_termios
,
500 (struct termios __user
*)arg
))
504 /* If old style Bfoo values are used then load c_ispeed/c_ospeed with the real speed
505 so its unconditionally usable */
506 tmp_termios
.c_ispeed
= tty_termios_input_baud_rate(&tmp_termios
);
507 tmp_termios
.c_ospeed
= tty_termios_baud_rate(&tmp_termios
);
509 ld
= tty_ldisc_ref(tty
);
512 if ((opt
& TERMIOS_FLUSH
) && ld
->flush_buffer
)
513 ld
->flush_buffer(tty
);
517 if (opt
& TERMIOS_WAIT
) {
518 tty_wait_until_sent(tty
, 0);
519 if (signal_pending(current
))
523 change_termios(tty
, &tmp_termios
);
525 /* FIXME: Arguably if tmp_termios == tty->termios AND the
526 actual requested termios was not tmp_termios then we may
527 want to return an error as no user requested change has
532 static int get_termio(struct tty_struct
* tty
, struct termio __user
* termio
)
534 if (kernel_termios_to_user_termio(termio
, tty
->termios
))
539 static unsigned long inq_canon(struct tty_struct
* tty
)
543 if (!tty
->canon_data
|| !tty
->read_buf
)
545 head
= tty
->canon_head
;
546 tail
= tty
->read_tail
;
547 nr
= (head
- tail
) & (N_TTY_BUF_SIZE
-1);
548 /* Skip EOF-chars.. */
549 while (head
!= tail
) {
550 if (test_bit(tail
, tty
->read_flags
) &&
551 tty
->read_buf
[tail
] == __DISABLED_CHAR
)
553 tail
= (tail
+1) & (N_TTY_BUF_SIZE
-1);
560 * These are deprecated, but there is limited support..
562 * The "sg_flags" translation is a joke..
564 static int get_sgflags(struct tty_struct
* tty
)
568 if (!(tty
->termios
->c_lflag
& ICANON
)) {
569 if (tty
->termios
->c_lflag
& ISIG
)
570 flags
|= 0x02; /* cbreak */
572 flags
|= 0x20; /* raw */
574 if (tty
->termios
->c_lflag
& ECHO
)
575 flags
|= 0x08; /* echo */
576 if (tty
->termios
->c_oflag
& OPOST
)
577 if (tty
->termios
->c_oflag
& ONLCR
)
578 flags
|= 0x10; /* crmod */
582 static int get_sgttyb(struct tty_struct
* tty
, struct sgttyb __user
* sgttyb
)
586 mutex_lock(&tty
->termios_mutex
);
587 tmp
.sg_ispeed
= tty
->termios
->c_ispeed
;
588 tmp
.sg_ospeed
= tty
->termios
->c_ospeed
;
589 tmp
.sg_erase
= tty
->termios
->c_cc
[VERASE
];
590 tmp
.sg_kill
= tty
->termios
->c_cc
[VKILL
];
591 tmp
.sg_flags
= get_sgflags(tty
);
592 mutex_unlock(&tty
->termios_mutex
);
594 return copy_to_user(sgttyb
, &tmp
, sizeof(tmp
)) ? -EFAULT
: 0;
597 static void set_sgflags(struct ktermios
* termios
, int flags
)
599 termios
->c_iflag
= ICRNL
| IXON
;
600 termios
->c_oflag
= 0;
601 termios
->c_lflag
= ISIG
| ICANON
;
602 if (flags
& 0x02) { /* cbreak */
603 termios
->c_iflag
= 0;
604 termios
->c_lflag
&= ~ICANON
;
606 if (flags
& 0x08) { /* echo */
607 termios
->c_lflag
|= ECHO
| ECHOE
| ECHOK
|
608 ECHOCTL
| ECHOKE
| IEXTEN
;
610 if (flags
& 0x10) { /* crmod */
611 termios
->c_oflag
|= OPOST
| ONLCR
;
613 if (flags
& 0x20) { /* raw */
614 termios
->c_iflag
= 0;
615 termios
->c_lflag
&= ~(ISIG
| ICANON
);
617 if (!(termios
->c_lflag
& ICANON
)) {
618 termios
->c_cc
[VMIN
] = 1;
619 termios
->c_cc
[VTIME
] = 0;
624 * set_sgttyb - set legacy terminal values
625 * @tty: tty structure
626 * @sgttyb: pointer to old style terminal structure
628 * Updates a terminal from the legacy BSD style terminal information
631 * Locking: termios_sem
634 static int set_sgttyb(struct tty_struct
* tty
, struct sgttyb __user
* sgttyb
)
638 struct ktermios termios
;
640 retval
= tty_check_change(tty
);
644 if (copy_from_user(&tmp
, sgttyb
, sizeof(tmp
)))
647 mutex_lock(&tty
->termios_mutex
);
648 termios
= *tty
->termios
;
649 termios
.c_cc
[VERASE
] = tmp
.sg_erase
;
650 termios
.c_cc
[VKILL
] = tmp
.sg_kill
;
651 set_sgflags(&termios
, tmp
.sg_flags
);
652 /* Try and encode into Bfoo format */
654 tty_termios_encode_baud_rate(&termios
, termios
.c_ispeed
, termios
.c_ospeed
);
656 mutex_unlock(&tty
->termios_mutex
);
657 change_termios(tty
, &termios
);
663 static int get_tchars(struct tty_struct
* tty
, struct tchars __user
* tchars
)
667 tmp
.t_intrc
= tty
->termios
->c_cc
[VINTR
];
668 tmp
.t_quitc
= tty
->termios
->c_cc
[VQUIT
];
669 tmp
.t_startc
= tty
->termios
->c_cc
[VSTART
];
670 tmp
.t_stopc
= tty
->termios
->c_cc
[VSTOP
];
671 tmp
.t_eofc
= tty
->termios
->c_cc
[VEOF
];
672 tmp
.t_brkc
= tty
->termios
->c_cc
[VEOL2
]; /* what is brkc anyway? */
673 return copy_to_user(tchars
, &tmp
, sizeof(tmp
)) ? -EFAULT
: 0;
676 static int set_tchars(struct tty_struct
* tty
, struct tchars __user
* tchars
)
680 if (copy_from_user(&tmp
, tchars
, sizeof(tmp
)))
682 tty
->termios
->c_cc
[VINTR
] = tmp
.t_intrc
;
683 tty
->termios
->c_cc
[VQUIT
] = tmp
.t_quitc
;
684 tty
->termios
->c_cc
[VSTART
] = tmp
.t_startc
;
685 tty
->termios
->c_cc
[VSTOP
] = tmp
.t_stopc
;
686 tty
->termios
->c_cc
[VEOF
] = tmp
.t_eofc
;
687 tty
->termios
->c_cc
[VEOL2
] = tmp
.t_brkc
; /* what is brkc anyway? */
693 static int get_ltchars(struct tty_struct
* tty
, struct ltchars __user
* ltchars
)
697 tmp
.t_suspc
= tty
->termios
->c_cc
[VSUSP
];
698 tmp
.t_dsuspc
= tty
->termios
->c_cc
[VSUSP
]; /* what is dsuspc anyway? */
699 tmp
.t_rprntc
= tty
->termios
->c_cc
[VREPRINT
];
700 tmp
.t_flushc
= tty
->termios
->c_cc
[VEOL2
]; /* what is flushc anyway? */
701 tmp
.t_werasc
= tty
->termios
->c_cc
[VWERASE
];
702 tmp
.t_lnextc
= tty
->termios
->c_cc
[VLNEXT
];
703 return copy_to_user(ltchars
, &tmp
, sizeof(tmp
)) ? -EFAULT
: 0;
706 static int set_ltchars(struct tty_struct
* tty
, struct ltchars __user
* ltchars
)
710 if (copy_from_user(&tmp
, ltchars
, sizeof(tmp
)))
713 tty
->termios
->c_cc
[VSUSP
] = tmp
.t_suspc
;
714 tty
->termios
->c_cc
[VEOL2
] = tmp
.t_dsuspc
; /* what is dsuspc anyway? */
715 tty
->termios
->c_cc
[VREPRINT
] = tmp
.t_rprntc
;
716 tty
->termios
->c_cc
[VEOL2
] = tmp
.t_flushc
; /* what is flushc anyway? */
717 tty
->termios
->c_cc
[VWERASE
] = tmp
.t_werasc
;
718 tty
->termios
->c_cc
[VLNEXT
] = tmp
.t_lnextc
;
724 * send_prio_char - send priority character
726 * Send a high priority character to the tty even if stopped
728 * Locking: none for xchar method, write ordering for write method.
731 static int send_prio_char(struct tty_struct
*tty
, char ch
)
733 int was_stopped
= tty
->stopped
;
735 if (tty
->driver
->send_xchar
) {
736 tty
->driver
->send_xchar(tty
, ch
);
740 if (tty_write_lock(tty
, 0) < 0)
745 tty
->driver
->write(tty
, &ch
, 1);
748 tty_write_unlock(tty
);
753 * tty_mode_ioctl - mode related ioctls
754 * @tty: tty for the ioctl
755 * @file: file pointer for the tty
757 * @arg: ioctl argument
759 * Perform non line discipline specific mode control ioctls. This
760 * is designed to be called by line disciplines to ensure they provide
761 * consistent mode setting.
764 int tty_mode_ioctl(struct tty_struct
* tty
, struct file
*file
,
765 unsigned int cmd
, unsigned long arg
)
767 struct tty_struct
* real_tty
;
768 void __user
*p
= (void __user
*)arg
;
770 if (tty
->driver
->type
== TTY_DRIVER_TYPE_PTY
&&
771 tty
->driver
->subtype
== PTY_TYPE_MASTER
)
772 real_tty
= tty
->link
;
779 return get_sgttyb(real_tty
, (struct sgttyb __user
*) arg
);
782 return set_sgttyb(real_tty
, (struct sgttyb __user
*) arg
);
786 return get_tchars(real_tty
, p
);
788 return set_tchars(real_tty
, p
);
792 return get_ltchars(real_tty
, p
);
794 return set_ltchars(real_tty
, p
);
797 return set_termios(real_tty
, p
, TERMIOS_FLUSH
| TERMIOS_WAIT
| TERMIOS_OLD
);
799 return set_termios(real_tty
, p
, TERMIOS_WAIT
| TERMIOS_OLD
);
801 return set_termios(real_tty
, p
, TERMIOS_OLD
);
804 if (kernel_termios_to_user_termios((struct termios __user
*)arg
, real_tty
->termios
))
809 if (kernel_termios_to_user_termios_1((struct termios __user
*)arg
, real_tty
->termios
))
813 if (kernel_termios_to_user_termios((struct termios2 __user
*)arg
, real_tty
->termios
))
817 return set_termios(real_tty
, p
, TERMIOS_FLUSH
| TERMIOS_WAIT
);
819 return set_termios(real_tty
, p
, TERMIOS_WAIT
);
821 return set_termios(real_tty
, p
, 0);
824 return get_termio(real_tty
, p
);
826 return set_termios(real_tty
, p
, TERMIOS_FLUSH
| TERMIOS_WAIT
| TERMIOS_TERMIO
);
828 return set_termios(real_tty
, p
, TERMIOS_WAIT
| TERMIOS_TERMIO
);
830 return set_termios(real_tty
, p
, TERMIOS_TERMIO
);
833 if (kernel_termios_to_user_termios((struct termios __user
*)arg
, real_tty
->termios_locked
))
838 if (!capable(CAP_SYS_ADMIN
))
840 if (user_termios_to_kernel_termios(real_tty
->termios_locked
, (struct termios __user
*) arg
))
845 if (kernel_termios_to_user_termios_1((struct termios __user
*)arg
, real_tty
->termios_locked
))
850 if (!capable(CAP_SYS_ADMIN
))
852 if (user_termios_to_kernel_termios_1(real_tty
->termios_locked
, (struct termios __user
*) arg
))
857 return put_user(C_CLOCAL(tty
) ? 1 : 0, (int __user
*)arg
);
859 if (get_user(arg
, (unsigned int __user
*) arg
))
861 mutex_lock(&tty
->termios_mutex
);
862 tty
->termios
->c_cflag
=
863 ((tty
->termios
->c_cflag
& ~CLOCAL
) |
865 mutex_unlock(&tty
->termios_mutex
);
872 EXPORT_SYMBOL_GPL(tty_mode_ioctl
);
874 int tty_perform_flush(struct tty_struct
*tty
, unsigned long arg
)
876 struct tty_ldisc
*ld
;
877 int retval
= tty_check_change(tty
);
881 ld
= tty_ldisc_ref(tty
);
884 if (ld
&& ld
->flush_buffer
)
885 ld
->flush_buffer(tty
);
888 if (ld
&& ld
->flush_buffer
)
889 ld
->flush_buffer(tty
);
892 if (tty
->driver
->flush_buffer
)
893 tty
->driver
->flush_buffer(tty
);
903 EXPORT_SYMBOL_GPL(tty_perform_flush
);
905 int n_tty_ioctl(struct tty_struct
* tty
, struct file
* file
,
906 unsigned int cmd
, unsigned long arg
)
908 struct tty_struct
* real_tty
;
911 if (tty
->driver
->type
== TTY_DRIVER_TYPE_PTY
&&
912 tty
->driver
->subtype
== PTY_TYPE_MASTER
)
913 real_tty
= tty
->link
;
919 retval
= tty_check_change(tty
);
924 if (!tty
->flow_stopped
) {
925 tty
->flow_stopped
= 1;
930 if (tty
->flow_stopped
) {
931 tty
->flow_stopped
= 0;
936 if (STOP_CHAR(tty
) != __DISABLED_CHAR
)
937 return send_prio_char(tty
, STOP_CHAR(tty
));
940 if (START_CHAR(tty
) != __DISABLED_CHAR
)
941 return send_prio_char(tty
, START_CHAR(tty
));
948 return tty_perform_flush(tty
, arg
);
950 return put_user(tty
->driver
->chars_in_buffer
?
951 tty
->driver
->chars_in_buffer(tty
) : 0,
954 retval
= tty
->read_cnt
;
956 retval
= inq_canon(tty
);
957 return put_user(retval
, (unsigned int __user
*) arg
);
962 if (tty
->driver
->type
!= TTY_DRIVER_TYPE_PTY
||
963 tty
->driver
->subtype
!= PTY_TYPE_MASTER
)
965 if (get_user(pktmode
, (int __user
*) arg
))
970 tty
->link
->ctrl_status
= 0;
977 /* Try the mode commands */
978 return tty_mode_ioctl(tty
, file
, cmd
, arg
);
982 EXPORT_SYMBOL(n_tty_ioctl
);