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>
24 #include <linux/smp_lock.h>
27 #include <asm/uaccess.h>
28 #include <asm/system.h>
30 #undef TTY_DEBUG_WAIT_UNTIL_SENT
35 * Internal flag options for termios setting behavior
37 #define TERMIOS_FLUSH 1
38 #define TERMIOS_WAIT 2
39 #define TERMIOS_TERMIO 4
43 int tty_chars_in_buffer(struct tty_struct
*tty
)
45 if (tty
->ops
->chars_in_buffer
)
46 return tty
->ops
->chars_in_buffer(tty
);
51 EXPORT_SYMBOL(tty_chars_in_buffer
);
53 int tty_write_room(struct tty_struct
*tty
)
55 if (tty
->ops
->write_room
)
56 return tty
->ops
->write_room(tty
);
60 EXPORT_SYMBOL(tty_write_room
);
62 void tty_driver_flush_buffer(struct tty_struct
*tty
)
64 if (tty
->ops
->flush_buffer
)
65 tty
->ops
->flush_buffer(tty
);
68 EXPORT_SYMBOL(tty_driver_flush_buffer
);
72 * tty_wait_until_sent - wait for I/O to finish
73 * @tty: tty we are waiting for
74 * @timeout: how long we will wait
76 * Wait for characters pending in a tty driver to hit the wire, or
77 * for a timeout to occur (eg due to flow control)
82 void tty_wait_until_sent(struct tty_struct
*tty
, long timeout
)
84 #ifdef TTY_DEBUG_WAIT_UNTIL_SENT
87 printk(KERN_DEBUG
"%s wait until sent...\n", tty_name(tty
, buf
));
90 timeout
= MAX_SCHEDULE_TIMEOUT
;
91 if (wait_event_interruptible_timeout(tty
->write_wait
,
92 !tty_chars_in_buffer(tty
), timeout
) >= 0) {
93 if (tty
->ops
->wait_until_sent
)
94 tty
->ops
->wait_until_sent(tty
, timeout
);
97 EXPORT_SYMBOL(tty_wait_until_sent
);
99 static void unset_locked_termios(struct ktermios
*termios
,
100 struct ktermios
*old
,
101 struct ktermios
*locked
)
105 #define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
108 printk(KERN_WARNING
"Warning?!? termios_locked is NULL.\n");
112 NOSET_MASK(termios
->c_iflag
, old
->c_iflag
, locked
->c_iflag
);
113 NOSET_MASK(termios
->c_oflag
, old
->c_oflag
, locked
->c_oflag
);
114 NOSET_MASK(termios
->c_cflag
, old
->c_cflag
, locked
->c_cflag
);
115 NOSET_MASK(termios
->c_lflag
, old
->c_lflag
, locked
->c_lflag
);
116 termios
->c_line
= locked
->c_line
? old
->c_line
: termios
->c_line
;
117 for (i
= 0; i
< NCCS
; i
++)
118 termios
->c_cc
[i
] = locked
->c_cc
[i
] ?
119 old
->c_cc
[i
] : termios
->c_cc
[i
];
120 /* FIXME: What should we do for i/ospeed */
124 * Routine which returns the baud rate of the tty
126 * Note that the baud_table needs to be kept in sync with the
127 * include/asm/termbits.h file.
129 static const speed_t baud_table
[] = {
130 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
131 9600, 19200, 38400, 57600, 115200, 230400, 460800,
133 76800, 153600, 307200, 614400, 921600
135 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
136 2500000, 3000000, 3500000, 4000000
141 static const tcflag_t baud_bits
[] = {
142 B0
, B50
, B75
, B110
, B134
, B150
, B200
, B300
, B600
,
143 B1200
, B1800
, B2400
, B4800
, B9600
, B19200
, B38400
,
144 B57600
, B115200
, B230400
, B460800
, B500000
, B576000
,
145 B921600
, B1000000
, B1152000
, B1500000
, B2000000
, B2500000
,
146 B3000000
, B3500000
, B4000000
149 static const tcflag_t baud_bits
[] = {
150 B0
, B50
, B75
, B110
, B134
, B150
, B200
, B300
, B600
,
151 B1200
, B1800
, B2400
, B4800
, B9600
, B19200
, B38400
,
152 B57600
, B115200
, B230400
, B460800
, B76800
, B153600
,
153 B307200
, B614400
, B921600
157 static int n_baud_table
= ARRAY_SIZE(baud_table
);
160 * tty_termios_baud_rate
161 * @termios: termios structure
163 * Convert termios baud rate data into a speed. This should be called
164 * with the termios lock held if this termios is a terminal termios
165 * structure. May change the termios data. Device drivers can call this
166 * function but should use ->c_[io]speed directly as they are updated.
171 speed_t
tty_termios_baud_rate(struct ktermios
*termios
)
175 cbaud
= termios
->c_cflag
& CBAUD
;
178 /* Magic token for arbitary speed via c_ispeed/c_ospeed */
180 return termios
->c_ospeed
;
182 if (cbaud
& CBAUDEX
) {
185 if (cbaud
< 1 || cbaud
+ 15 > n_baud_table
)
186 termios
->c_cflag
&= ~CBAUDEX
;
190 return baud_table
[cbaud
];
192 EXPORT_SYMBOL(tty_termios_baud_rate
);
195 * tty_termios_input_baud_rate
196 * @termios: termios structure
198 * Convert termios baud rate data into a speed. This should be called
199 * with the termios lock held if this termios is a terminal termios
200 * structure. May change the termios data. Device drivers can call this
201 * function but should use ->c_[io]speed directly as they are updated.
206 speed_t
tty_termios_input_baud_rate(struct ktermios
*termios
)
209 unsigned int cbaud
= (termios
->c_cflag
>> IBSHIFT
) & CBAUD
;
212 return tty_termios_baud_rate(termios
);
214 /* Magic token for arbitary speed via c_ispeed*/
216 return termios
->c_ispeed
;
218 if (cbaud
& CBAUDEX
) {
221 if (cbaud
< 1 || cbaud
+ 15 > n_baud_table
)
222 termios
->c_cflag
&= ~(CBAUDEX
<< IBSHIFT
);
226 return baud_table
[cbaud
];
228 return tty_termios_baud_rate(termios
);
231 EXPORT_SYMBOL(tty_termios_input_baud_rate
);
234 * tty_termios_encode_baud_rate
235 * @termios: ktermios structure holding user requested state
236 * @ispeed: input speed
237 * @ospeed: output speed
239 * Encode the speeds set into the passed termios structure. This is
240 * used as a library helper for drivers os that they can report back
241 * the actual speed selected when it differs from the speed requested
243 * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
244 * we need to carefully set the bits when the user does not get the
245 * desired speed. We allow small margins and preserve as much of possible
246 * of the input intent to keep compatiblity.
248 * Locking: Caller should hold termios lock. This is already held
249 * when calling this function from the driver termios handler.
251 * The ifdefs deal with platforms whose owners have yet to update them
252 * and will all go away once this is done.
255 void tty_termios_encode_baud_rate(struct ktermios
*termios
,
256 speed_t ibaud
, speed_t obaud
)
259 int ifound
= -1, ofound
= -1;
260 int iclose
= ibaud
/50, oclose
= obaud
/50;
263 if (obaud
== 0) /* CD dropped */
264 ibaud
= 0; /* Clear ibaud to be sure */
266 termios
->c_ispeed
= ibaud
;
267 termios
->c_ospeed
= obaud
;
270 /* If the user asked for a precise weird speed give a precise weird
271 answer. If they asked for a Bfoo speed they many have problems
272 digesting non-exact replies so fuzz a bit */
274 if ((termios
->c_cflag
& CBAUD
) == BOTHER
)
276 if (((termios
->c_cflag
>> IBSHIFT
) & CBAUD
) == BOTHER
)
278 if ((termios
->c_cflag
>> IBSHIFT
) & CBAUD
)
279 ibinput
= 1; /* An input speed was specified */
281 termios
->c_cflag
&= ~CBAUD
;
284 * Our goal is to find a close match to the standard baud rate
285 * returned. Walk the baud rate table and if we get a very close
286 * match then report back the speed as a POSIX Bxxxx value by
291 if (obaud
- oclose
<= baud_table
[i
] &&
292 obaud
+ oclose
>= baud_table
[i
]) {
293 termios
->c_cflag
|= baud_bits
[i
];
296 if (ibaud
- iclose
<= baud_table
[i
] &&
297 ibaud
+ iclose
>= baud_table
[i
]) {
298 /* For the case input == output don't set IBAUD bits
299 if the user didn't do so */
300 if (ofound
== i
&& !ibinput
)
305 termios
->c_cflag
|= (baud_bits
[i
] << IBSHIFT
);
309 } while (++i
< n_baud_table
);
312 * If we found no match then use BOTHER if provided or warn
313 * the user their platform maintainer needs to wake up if not.
317 termios
->c_cflag
|= BOTHER
;
318 /* Set exact input bits only if the input and output differ or the
320 if (ifound
== -1 && (ibaud
!= obaud
|| ibinput
))
321 termios
->c_cflag
|= (BOTHER
<< IBSHIFT
);
323 if (ifound
== -1 || ofound
== -1) {
326 printk(KERN_WARNING
"tty: Unable to return correct "
327 "speed data as your architecture needs updating.\n");
331 EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate
);
333 void tty_encode_baud_rate(struct tty_struct
*tty
, speed_t ibaud
, speed_t obaud
)
335 tty_termios_encode_baud_rate(tty
->termios
, ibaud
, obaud
);
337 EXPORT_SYMBOL_GPL(tty_encode_baud_rate
);
340 * tty_get_baud_rate - get tty bit rates
343 * Returns the baud rate as an integer for this terminal. The
344 * termios lock must be held by the caller and the terminal bit
345 * flags may be updated.
350 speed_t
tty_get_baud_rate(struct tty_struct
*tty
)
352 speed_t baud
= tty_termios_baud_rate(tty
->termios
);
354 if (baud
== 38400 && tty
->alt_speed
) {
356 printk(KERN_WARNING
"Use of setserial/setrocket to "
357 "set SPD_* flags is deprecated\n");
360 baud
= tty
->alt_speed
;
365 EXPORT_SYMBOL(tty_get_baud_rate
);
368 * tty_termios_copy_hw - copy hardware settings
372 * Propogate the hardware specific terminal setting bits from
373 * the old termios structure to the new one. This is used in cases
374 * where the hardware does not support reconfiguration or as a helper
375 * in some cases where only minimal reconfiguration is supported
378 void tty_termios_copy_hw(struct ktermios
*new, struct ktermios
*old
)
380 /* The bits a dumb device handles in software. Smart devices need
381 to always provide a set_termios method */
382 new->c_cflag
&= HUPCL
| CREAD
| CLOCAL
;
383 new->c_cflag
|= old
->c_cflag
& ~(HUPCL
| CREAD
| CLOCAL
);
384 new->c_ispeed
= old
->c_ispeed
;
385 new->c_ospeed
= old
->c_ospeed
;
387 EXPORT_SYMBOL(tty_termios_copy_hw
);
390 * tty_termios_hw_change - check for setting change
392 * @b: termios to compare
394 * Check if any of the bits that affect a dumb device have changed
395 * between the two termios structures, or a speed change is needed.
398 int tty_termios_hw_change(struct ktermios
*a
, struct ktermios
*b
)
400 if (a
->c_ispeed
!= b
->c_ispeed
|| a
->c_ospeed
!= b
->c_ospeed
)
402 if ((a
->c_cflag
^ b
->c_cflag
) & ~(HUPCL
| CREAD
| CLOCAL
))
406 EXPORT_SYMBOL(tty_termios_hw_change
);
409 * change_termios - update termios values
410 * @tty: tty to update
411 * @new_termios: desired new value
413 * Perform updates to the termios values set on this terminal. There
414 * is a bit of layering violation here with n_tty in terms of the
415 * internal knowledge of this function.
417 * Locking: termios_sem
420 static void change_termios(struct tty_struct
*tty
, struct ktermios
*new_termios
)
423 struct ktermios old_termios
;
424 struct tty_ldisc
*ld
;
428 * Perform the actual termios internal changes under lock.
432 /* FIXME: we need to decide on some locking/ordering semantics
433 for the set_termios notification eventually */
434 mutex_lock(&tty
->termios_mutex
);
435 old_termios
= *tty
->termios
;
436 *tty
->termios
= *new_termios
;
437 unset_locked_termios(tty
->termios
, &old_termios
, tty
->termios_locked
);
438 canon_change
= (old_termios
.c_lflag
^ tty
->termios
->c_lflag
) & ICANON
;
440 memset(&tty
->read_flags
, 0, sizeof tty
->read_flags
);
441 tty
->canon_head
= tty
->read_tail
;
446 /* This bit should be in the ldisc code */
447 if (canon_change
&& !L_ICANON(tty
) && tty
->read_cnt
)
448 /* Get characters left over from canonical mode. */
449 wake_up_interruptible(&tty
->read_wait
);
451 /* See if packet mode change of state. */
452 if (tty
->link
&& tty
->link
->packet
) {
453 int old_flow
= ((old_termios
.c_iflag
& IXON
) &&
454 (old_termios
.c_cc
[VSTOP
] == '\023') &&
455 (old_termios
.c_cc
[VSTART
] == '\021'));
456 int new_flow
= (I_IXON(tty
) &&
457 STOP_CHAR(tty
) == '\023' &&
458 START_CHAR(tty
) == '\021');
459 if (old_flow
!= new_flow
) {
460 spin_lock_irqsave(&tty
->ctrl_lock
, flags
);
461 tty
->ctrl_status
&= ~(TIOCPKT_DOSTOP
| TIOCPKT_NOSTOP
);
463 tty
->ctrl_status
|= TIOCPKT_DOSTOP
;
465 tty
->ctrl_status
|= TIOCPKT_NOSTOP
;
466 spin_unlock_irqrestore(&tty
->ctrl_lock
, flags
);
467 wake_up_interruptible(&tty
->link
->read_wait
);
471 if (tty
->ops
->set_termios
)
472 (*tty
->ops
->set_termios
)(tty
, &old_termios
);
474 tty_termios_copy_hw(tty
->termios
, &old_termios
);
476 ld
= tty_ldisc_ref(tty
);
479 (ld
->set_termios
)(tty
, &old_termios
);
482 mutex_unlock(&tty
->termios_mutex
);
486 * set_termios - set termios values for a tty
487 * @tty: terminal device
489 * @opt: option information
491 * Helper function to prepare termios data and run necessary other
492 * functions before using change_termios to do the actual changes.
495 * Called functions take ldisc and termios_sem locks
498 static int set_termios(struct tty_struct
*tty
, void __user
*arg
, int opt
)
500 struct ktermios tmp_termios
;
501 struct tty_ldisc
*ld
;
502 int retval
= tty_check_change(tty
);
507 mutex_lock(&tty
->termios_mutex
);
508 memcpy(&tmp_termios
, tty
->termios
, sizeof(struct ktermios
));
509 mutex_unlock(&tty
->termios_mutex
);
511 if (opt
& TERMIOS_TERMIO
) {
512 if (user_termio_to_kernel_termios(&tmp_termios
,
513 (struct termio __user
*)arg
))
516 } else if (opt
& TERMIOS_OLD
) {
517 if (user_termios_to_kernel_termios_1(&tmp_termios
,
518 (struct termios __user
*)arg
))
521 if (user_termios_to_kernel_termios(&tmp_termios
,
522 (struct termios2 __user
*)arg
))
526 } else if (user_termios_to_kernel_termios(&tmp_termios
,
527 (struct termios __user
*)arg
))
531 /* If old style Bfoo values are used then load c_ispeed/c_ospeed
532 * with the real speed so its unconditionally usable */
533 tmp_termios
.c_ispeed
= tty_termios_input_baud_rate(&tmp_termios
);
534 tmp_termios
.c_ospeed
= tty_termios_baud_rate(&tmp_termios
);
536 ld
= tty_ldisc_ref(tty
);
539 if ((opt
& TERMIOS_FLUSH
) && ld
->flush_buffer
)
540 ld
->flush_buffer(tty
);
544 if (opt
& TERMIOS_WAIT
) {
545 tty_wait_until_sent(tty
, 0);
546 if (signal_pending(current
))
550 change_termios(tty
, &tmp_termios
);
552 /* FIXME: Arguably if tmp_termios == tty->termios AND the
553 actual requested termios was not tmp_termios then we may
554 want to return an error as no user requested change has
559 static int get_termio(struct tty_struct
*tty
, struct termio __user
*termio
)
561 if (kernel_termios_to_user_termio(termio
, tty
->termios
))
566 static unsigned long inq_canon(struct tty_struct
*tty
)
570 if (!tty
->canon_data
|| !tty
->read_buf
)
572 head
= tty
->canon_head
;
573 tail
= tty
->read_tail
;
574 nr
= (head
- tail
) & (N_TTY_BUF_SIZE
-1);
575 /* Skip EOF-chars.. */
576 while (head
!= tail
) {
577 if (test_bit(tail
, tty
->read_flags
) &&
578 tty
->read_buf
[tail
] == __DISABLED_CHAR
)
580 tail
= (tail
+1) & (N_TTY_BUF_SIZE
-1);
587 * These are deprecated, but there is limited support..
589 * The "sg_flags" translation is a joke..
591 static int get_sgflags(struct tty_struct
*tty
)
595 if (!(tty
->termios
->c_lflag
& ICANON
)) {
596 if (tty
->termios
->c_lflag
& ISIG
)
597 flags
|= 0x02; /* cbreak */
599 flags
|= 0x20; /* raw */
601 if (tty
->termios
->c_lflag
& ECHO
)
602 flags
|= 0x08; /* echo */
603 if (tty
->termios
->c_oflag
& OPOST
)
604 if (tty
->termios
->c_oflag
& ONLCR
)
605 flags
|= 0x10; /* crmod */
609 static int get_sgttyb(struct tty_struct
*tty
, struct sgttyb __user
*sgttyb
)
613 mutex_lock(&tty
->termios_mutex
);
614 tmp
.sg_ispeed
= tty
->termios
->c_ispeed
;
615 tmp
.sg_ospeed
= tty
->termios
->c_ospeed
;
616 tmp
.sg_erase
= tty
->termios
->c_cc
[VERASE
];
617 tmp
.sg_kill
= tty
->termios
->c_cc
[VKILL
];
618 tmp
.sg_flags
= get_sgflags(tty
);
619 mutex_unlock(&tty
->termios_mutex
);
621 return copy_to_user(sgttyb
, &tmp
, sizeof(tmp
)) ? -EFAULT
: 0;
624 static void set_sgflags(struct ktermios
*termios
, int flags
)
626 termios
->c_iflag
= ICRNL
| IXON
;
627 termios
->c_oflag
= 0;
628 termios
->c_lflag
= ISIG
| ICANON
;
629 if (flags
& 0x02) { /* cbreak */
630 termios
->c_iflag
= 0;
631 termios
->c_lflag
&= ~ICANON
;
633 if (flags
& 0x08) { /* echo */
634 termios
->c_lflag
|= ECHO
| ECHOE
| ECHOK
|
635 ECHOCTL
| ECHOKE
| IEXTEN
;
637 if (flags
& 0x10) { /* crmod */
638 termios
->c_oflag
|= OPOST
| ONLCR
;
640 if (flags
& 0x20) { /* raw */
641 termios
->c_iflag
= 0;
642 termios
->c_lflag
&= ~(ISIG
| ICANON
);
644 if (!(termios
->c_lflag
& ICANON
)) {
645 termios
->c_cc
[VMIN
] = 1;
646 termios
->c_cc
[VTIME
] = 0;
651 * set_sgttyb - set legacy terminal values
652 * @tty: tty structure
653 * @sgttyb: pointer to old style terminal structure
655 * Updates a terminal from the legacy BSD style terminal information
658 * Locking: termios_sem
661 static int set_sgttyb(struct tty_struct
*tty
, struct sgttyb __user
*sgttyb
)
665 struct ktermios termios
;
667 retval
= tty_check_change(tty
);
671 if (copy_from_user(&tmp
, sgttyb
, sizeof(tmp
)))
674 mutex_lock(&tty
->termios_mutex
);
675 termios
= *tty
->termios
;
676 termios
.c_cc
[VERASE
] = tmp
.sg_erase
;
677 termios
.c_cc
[VKILL
] = tmp
.sg_kill
;
678 set_sgflags(&termios
, tmp
.sg_flags
);
679 /* Try and encode into Bfoo format */
681 tty_termios_encode_baud_rate(&termios
, termios
.c_ispeed
,
684 mutex_unlock(&tty
->termios_mutex
);
685 change_termios(tty
, &termios
);
691 static int get_tchars(struct tty_struct
*tty
, struct tchars __user
*tchars
)
695 mutex_lock(&tty
->termios_mutex
);
696 tmp
.t_intrc
= tty
->termios
->c_cc
[VINTR
];
697 tmp
.t_quitc
= tty
->termios
->c_cc
[VQUIT
];
698 tmp
.t_startc
= tty
->termios
->c_cc
[VSTART
];
699 tmp
.t_stopc
= tty
->termios
->c_cc
[VSTOP
];
700 tmp
.t_eofc
= tty
->termios
->c_cc
[VEOF
];
701 tmp
.t_brkc
= tty
->termios
->c_cc
[VEOL2
]; /* what is brkc anyway? */
702 mutex_unlock(&tty
->termios_mutex
);
703 return copy_to_user(tchars
, &tmp
, sizeof(tmp
)) ? -EFAULT
: 0;
706 static int set_tchars(struct tty_struct
*tty
, struct tchars __user
*tchars
)
710 if (copy_from_user(&tmp
, tchars
, sizeof(tmp
)))
712 mutex_lock(&tty
->termios_mutex
);
713 tty
->termios
->c_cc
[VINTR
] = tmp
.t_intrc
;
714 tty
->termios
->c_cc
[VQUIT
] = tmp
.t_quitc
;
715 tty
->termios
->c_cc
[VSTART
] = tmp
.t_startc
;
716 tty
->termios
->c_cc
[VSTOP
] = tmp
.t_stopc
;
717 tty
->termios
->c_cc
[VEOF
] = tmp
.t_eofc
;
718 tty
->termios
->c_cc
[VEOL2
] = tmp
.t_brkc
; /* what is brkc anyway? */
719 mutex_unlock(&tty
->termios_mutex
);
725 static int get_ltchars(struct tty_struct
*tty
, struct ltchars __user
*ltchars
)
729 mutex_lock(&tty
->termios_mutex
);
730 tmp
.t_suspc
= tty
->termios
->c_cc
[VSUSP
];
731 /* what is dsuspc anyway? */
732 tmp
.t_dsuspc
= tty
->termios
->c_cc
[VSUSP
];
733 tmp
.t_rprntc
= tty
->termios
->c_cc
[VREPRINT
];
734 /* what is flushc anyway? */
735 tmp
.t_flushc
= tty
->termios
->c_cc
[VEOL2
];
736 tmp
.t_werasc
= tty
->termios
->c_cc
[VWERASE
];
737 tmp
.t_lnextc
= tty
->termios
->c_cc
[VLNEXT
];
738 mutex_unlock(&tty
->termios_mutex
);
739 return copy_to_user(ltchars
, &tmp
, sizeof(tmp
)) ? -EFAULT
: 0;
742 static int set_ltchars(struct tty_struct
*tty
, struct ltchars __user
*ltchars
)
746 if (copy_from_user(&tmp
, ltchars
, sizeof(tmp
)))
749 mutex_lock(&tty
->termios_mutex
);
750 tty
->termios
->c_cc
[VSUSP
] = tmp
.t_suspc
;
751 /* what is dsuspc anyway? */
752 tty
->termios
->c_cc
[VEOL2
] = tmp
.t_dsuspc
;
753 tty
->termios
->c_cc
[VREPRINT
] = tmp
.t_rprntc
;
754 /* what is flushc anyway? */
755 tty
->termios
->c_cc
[VEOL2
] = tmp
.t_flushc
;
756 tty
->termios
->c_cc
[VWERASE
] = tmp
.t_werasc
;
757 tty
->termios
->c_cc
[VLNEXT
] = tmp
.t_lnextc
;
758 mutex_unlock(&tty
->termios_mutex
);
764 * send_prio_char - send priority character
766 * Send a high priority character to the tty even if stopped
768 * Locking: none for xchar method, write ordering for write method.
771 static int send_prio_char(struct tty_struct
*tty
, char ch
)
773 int was_stopped
= tty
->stopped
;
775 if (tty
->ops
->send_xchar
) {
776 tty
->ops
->send_xchar(tty
, ch
);
780 if (tty_write_lock(tty
, 0) < 0)
785 tty
->ops
->write(tty
, &ch
, 1);
788 tty_write_unlock(tty
);
793 * tty_change_softcar - carrier change ioctl helper
794 * @tty: tty to update
795 * @arg: enable/disable CLOCAL
797 * Perform a change to the CLOCAL state and call into the driver
798 * layer to make it visible. All done with the termios mutex
801 static int tty_change_softcar(struct tty_struct
*tty
, int arg
)
804 int bit
= arg
? CLOCAL
: 0;
807 mutex_lock(&tty
->termios_mutex
);
809 tty
->termios
->c_cflag
&= ~CLOCAL
;
810 tty
->termios
->c_cflag
|= bit
;
811 if (tty
->ops
->set_termios
)
812 tty
->ops
->set_termios(tty
, &old
);
813 if ((tty
->termios
->c_cflag
& CLOCAL
) != bit
)
815 mutex_unlock(&tty
->termios_mutex
);
820 * tty_mode_ioctl - mode related ioctls
821 * @tty: tty for the ioctl
822 * @file: file pointer for the tty
824 * @arg: ioctl argument
826 * Perform non line discipline specific mode control ioctls. This
827 * is designed to be called by line disciplines to ensure they provide
828 * consistent mode setting.
831 int tty_mode_ioctl(struct tty_struct
*tty
, struct file
*file
,
832 unsigned int cmd
, unsigned long arg
)
834 struct tty_struct
*real_tty
;
835 void __user
*p
= (void __user
*)arg
;
837 if (tty
->driver
->type
== TTY_DRIVER_TYPE_PTY
&&
838 tty
->driver
->subtype
== PTY_TYPE_MASTER
)
839 real_tty
= tty
->link
;
846 return get_sgttyb(real_tty
, (struct sgttyb __user
*) arg
);
849 return set_sgttyb(real_tty
, (struct sgttyb __user
*) arg
);
853 return get_tchars(real_tty
, p
);
855 return set_tchars(real_tty
, p
);
859 return get_ltchars(real_tty
, p
);
861 return set_ltchars(real_tty
, p
);
864 return set_termios(real_tty
, p
, TERMIOS_FLUSH
| TERMIOS_WAIT
| TERMIOS_OLD
);
866 return set_termios(real_tty
, p
, TERMIOS_WAIT
| TERMIOS_OLD
);
868 return set_termios(real_tty
, p
, TERMIOS_OLD
);
871 if (kernel_termios_to_user_termios((struct termios __user
*)arg
, real_tty
->termios
))
876 if (kernel_termios_to_user_termios_1((struct termios __user
*)arg
, real_tty
->termios
))
880 if (kernel_termios_to_user_termios((struct termios2 __user
*)arg
, real_tty
->termios
))
884 return set_termios(real_tty
, p
, TERMIOS_FLUSH
| TERMIOS_WAIT
);
886 return set_termios(real_tty
, p
, TERMIOS_WAIT
);
888 return set_termios(real_tty
, p
, 0);
891 return get_termio(real_tty
, p
);
893 return set_termios(real_tty
, p
, TERMIOS_FLUSH
| TERMIOS_WAIT
| TERMIOS_TERMIO
);
895 return set_termios(real_tty
, p
, TERMIOS_WAIT
| TERMIOS_TERMIO
);
897 return set_termios(real_tty
, p
, TERMIOS_TERMIO
);
900 if (kernel_termios_to_user_termios((struct termios __user
*)arg
, real_tty
->termios_locked
))
904 if (!capable(CAP_SYS_ADMIN
))
906 if (user_termios_to_kernel_termios(real_tty
->termios_locked
,
907 (struct termios __user
*) arg
))
912 if (kernel_termios_to_user_termios_1((struct termios __user
*)arg
, real_tty
->termios_locked
))
916 if (!capable(CAP_SYS_ADMIN
))
918 if (user_termios_to_kernel_termios_1(real_tty
->termios_locked
,
919 (struct termios __user
*) arg
))
924 return put_user(C_CLOCAL(tty
) ? 1 : 0,
927 if (get_user(arg
, (unsigned int __user
*) arg
))
929 return tty_change_softcar(tty
, arg
);
934 EXPORT_SYMBOL_GPL(tty_mode_ioctl
);
936 int tty_perform_flush(struct tty_struct
*tty
, unsigned long arg
)
938 struct tty_ldisc
*ld
;
939 int retval
= tty_check_change(tty
);
943 ld
= tty_ldisc_ref(tty
);
946 if (ld
&& ld
->flush_buffer
)
947 ld
->flush_buffer(tty
);
950 if (ld
&& ld
->flush_buffer
)
951 ld
->flush_buffer(tty
);
954 tty_driver_flush_buffer(tty
);
963 EXPORT_SYMBOL_GPL(tty_perform_flush
);
965 int n_tty_ioctl(struct tty_struct
*tty
, struct file
*file
,
966 unsigned int cmd
, unsigned long arg
)
968 struct tty_struct
*real_tty
;
972 if (tty
->driver
->type
== TTY_DRIVER_TYPE_PTY
&&
973 tty
->driver
->subtype
== PTY_TYPE_MASTER
)
974 real_tty
= tty
->link
;
980 retval
= tty_check_change(tty
);
985 if (!tty
->flow_stopped
) {
986 tty
->flow_stopped
= 1;
991 if (tty
->flow_stopped
) {
992 tty
->flow_stopped
= 0;
997 if (STOP_CHAR(tty
) != __DISABLED_CHAR
)
998 return send_prio_char(tty
, STOP_CHAR(tty
));
1001 if (START_CHAR(tty
) != __DISABLED_CHAR
)
1002 return send_prio_char(tty
, START_CHAR(tty
));
1009 return tty_perform_flush(tty
, arg
);
1011 return put_user(tty_chars_in_buffer(tty
), (int __user
*) arg
);
1013 retval
= tty
->read_cnt
;
1015 retval
= inq_canon(tty
);
1016 return put_user(retval
, (unsigned int __user
*) arg
);
1021 if (tty
->driver
->type
!= TTY_DRIVER_TYPE_PTY
||
1022 tty
->driver
->subtype
!= PTY_TYPE_MASTER
)
1024 if (get_user(pktmode
, (int __user
*) arg
))
1026 spin_lock_irqsave(&tty
->ctrl_lock
, flags
);
1030 tty
->link
->ctrl_status
= 0;
1034 spin_unlock_irqrestore(&tty
->ctrl_lock
, flags
);
1038 /* Try the mode commands */
1039 return tty_mode_ioctl(tty
, file
, cmd
, arg
);
1042 EXPORT_SYMBOL(n_tty_ioctl
);