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