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