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