UDF: check for allocated memory for data of new inodes
[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
AC
41
42/**
43 * tty_wait_until_sent - wait for I/O to finish
44 * @tty: tty we are waiting for
45 * @timeout: how long we will wait
46 *
47 * Wait for characters pending in a tty driver to hit the wire, or
48 * for a timeout to occur (eg due to flow control)
49 *
50 * Locking: none
51 */
52
1da177e4
LT
53void tty_wait_until_sent(struct tty_struct * tty, long timeout)
54{
55 DECLARE_WAITQUEUE(wait, current);
56
57#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
58 char buf[64];
59
60 printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
61#endif
62 if (!tty->driver->chars_in_buffer)
63 return;
64 add_wait_queue(&tty->write_wait, &wait);
65 if (!timeout)
66 timeout = MAX_SCHEDULE_TIMEOUT;
67 do {
68#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
69 printk(KERN_DEBUG "waiting %s...(%d)\n", tty_name(tty, buf),
70 tty->driver->chars_in_buffer(tty));
71#endif
72 set_current_state(TASK_INTERRUPTIBLE);
73 if (signal_pending(current))
74 goto stop_waiting;
75 if (!tty->driver->chars_in_buffer(tty))
76 break;
77 timeout = schedule_timeout(timeout);
78 } while (timeout);
79 if (tty->driver->wait_until_sent)
80 tty->driver->wait_until_sent(tty, timeout);
81stop_waiting:
82 set_current_state(TASK_RUNNING);
83 remove_wait_queue(&tty->write_wait, &wait);
84}
85
86EXPORT_SYMBOL(tty_wait_until_sent);
87
edc6afc5
AC
88static void unset_locked_termios(struct ktermios *termios,
89 struct ktermios *old,
90 struct ktermios *locked)
1da177e4
LT
91{
92 int i;
93
94#define NOSET_MASK(x,y,z) (x = ((x) & ~(z)) | ((y) & (z)))
95
96 if (!locked) {
97 printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
98 return;
99 }
100
101 NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
102 NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
103 NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
104 NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
105 termios->c_line = locked->c_line ? old->c_line : termios->c_line;
106 for (i=0; i < NCCS; i++)
107 termios->c_cc[i] = locked->c_cc[i] ?
108 old->c_cc[i] : termios->c_cc[i];
edc6afc5 109 /* FIXME: What should we do for i/ospeed */
1da177e4
LT
110}
111
edc6afc5
AC
112/*
113 * Routine which returns the baud rate of the tty
114 *
115 * Note that the baud_table needs to be kept in sync with the
116 * include/asm/termbits.h file.
117 */
118static const speed_t baud_table[] = {
119 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
120 9600, 19200, 38400, 57600, 115200, 230400, 460800,
121#ifdef __sparc__
122 76800, 153600, 307200, 614400, 921600
123#else
124 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
125 2500000, 3000000, 3500000, 4000000
126#endif
127};
128
129#ifndef __sparc__
130static const tcflag_t baud_bits[] = {
131 B0, B50, B75, B110, B134, B150, B200, B300, B600,
132 B1200, B1800, B2400, B4800, B9600, B19200, B38400,
133 B57600, B115200, B230400, B460800, B500000, B576000,
134 B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
135 B3000000, B3500000, B4000000
136};
137#else
138static const tcflag_t baud_bits[] = {
139 B0, B50, B75, B110, B134, B150, B200, B300, B600,
140 B1200, B1800, B2400, B4800, B9600, B19200, B38400,
141 B57600, B115200, B230400, B460800, B76800, B153600,
142 B307200, B614400, B921600
143};
144#endif
145
146static int n_baud_table = ARRAY_SIZE(baud_table);
147
148/**
149 * tty_termios_baud_rate
150 * @termios: termios structure
151 *
152 * Convert termios baud rate data into a speed. This should be called
153 * with the termios lock held if this termios is a terminal termios
154 * structure. May change the termios data. Device drivers can call this
155 * function but should use ->c_[io]speed directly as they are updated.
156 *
157 * Locking: none
158 */
159
160speed_t tty_termios_baud_rate(struct ktermios *termios)
161{
162 unsigned int cbaud;
163
164 cbaud = termios->c_cflag & CBAUD;
165
166#ifdef BOTHER
167 /* Magic token for arbitary speed via c_ispeed/c_ospeed */
168 if (cbaud == BOTHER)
169 return termios->c_ospeed;
170#endif
171 if (cbaud & CBAUDEX) {
172 cbaud &= ~CBAUDEX;
173
174 if (cbaud < 1 || cbaud + 15 > n_baud_table)
175 termios->c_cflag &= ~CBAUDEX;
176 else
177 cbaud += 15;
178 }
179 return baud_table[cbaud];
180}
181
182EXPORT_SYMBOL(tty_termios_baud_rate);
183
184/**
185 * tty_termios_input_baud_rate
186 * @termios: termios structure
187 *
188 * Convert termios baud rate data into a speed. This should be called
189 * with the termios lock held if this termios is a terminal termios
190 * structure. May change the termios data. Device drivers can call this
191 * function but should use ->c_[io]speed directly as they are updated.
192 *
193 * Locking: none
194 */
195
196speed_t tty_termios_input_baud_rate(struct ktermios *termios)
197{
198#ifdef IBSHIFT
199 unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
200
201 if (cbaud == B0)
202 return tty_termios_baud_rate(termios);
203
204 /* Magic token for arbitary speed via c_ispeed*/
205 if (cbaud == BOTHER)
206 return termios->c_ispeed;
207
208 if (cbaud & CBAUDEX) {
209 cbaud &= ~CBAUDEX;
210
211 if (cbaud < 1 || cbaud + 15 > n_baud_table)
212 termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
213 else
214 cbaud += 15;
215 }
216 return baud_table[cbaud];
217#else
218 return tty_termios_baud_rate(termios);
219#endif
220}
221
222EXPORT_SYMBOL(tty_termios_input_baud_rate);
223
224#ifdef BOTHER
225
226/**
227 * tty_termios_encode_baud_rate
78137e3b 228 * @termios: ktermios structure holding user requested state
edc6afc5
AC
229 * @ispeed: input speed
230 * @ospeed: output speed
231 *
232 * Encode the speeds set into the passed termios structure. This is
233 * used as a library helper for drivers os that they can report back
234 * the actual speed selected when it differs from the speed requested
235 *
78137e3b
AC
236 * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
237 * we need to carefully set the bits when the user does not get the
238 * desired speed. We allow small margins and preserve as much of possible
239 * of the input intent to keep compatiblity.
edc6afc5
AC
240 *
241 * Locking: Caller should hold termios lock. This is already held
242 * when calling this function from the driver termios handler.
243 */
244
245void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud)
246{
247 int i = 0;
78137e3b
AC
248 int ifound = -1, ofound = -1;
249 int iclose = ibaud/50, oclose = obaud/50;
250 int ibinput = 0;
edc6afc5
AC
251
252 termios->c_ispeed = ibaud;
253 termios->c_ospeed = obaud;
254
78137e3b
AC
255 /* If the user asked for a precise weird speed give a precise weird
256 answer. If they asked for a Bfoo speed they many have problems
257 digesting non-exact replies so fuzz a bit */
258
259 if ((termios->c_cflag & CBAUD) == BOTHER)
260 oclose = 0;
261 if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER)
262 iclose = 0;
263 if ((termios->c_cflag >> IBSHIFT) & CBAUD)
264 ibinput = 1; /* An input speed was specified */
265
edc6afc5 266 termios->c_cflag &= ~CBAUD;
edc6afc5
AC
267
268 do {
78137e3b 269 if (obaud - oclose >= baud_table[i] && obaud + oclose <= baud_table[i]) {
edc6afc5 270 termios->c_cflag |= baud_bits[i];
78137e3b 271 ofound = i;
edc6afc5 272 }
78137e3b
AC
273 if (ibaud - iclose >= baud_table[i] && ibaud + iclose <= baud_table[i]) {
274 /* For the case input == output don't set IBAUD bits if the user didn't do so */
275 if (ofound != i || ibinput)
276 termios->c_cflag |= (baud_bits[i] << IBSHIFT);
277 ifound = i;
edc6afc5
AC
278 }
279 }
280 while(++i < n_baud_table);
78137e3b 281 if (ofound == -1)
edc6afc5 282 termios->c_cflag |= BOTHER;
78137e3b
AC
283 /* Set exact input bits only if the input and output differ or the
284 user already did */
285 if (ifound == -1 && (ibaud != obaud || ibinput))
edc6afc5
AC
286 termios->c_cflag |= (BOTHER << IBSHIFT);
287}
288
289EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
290
291#endif
292
293/**
294 * tty_get_baud_rate - get tty bit rates
295 * @tty: tty to query
296 *
297 * Returns the baud rate as an integer for this terminal. The
298 * termios lock must be held by the caller and the terminal bit
299 * flags may be updated.
300 *
301 * Locking: none
302 */
303
304speed_t tty_get_baud_rate(struct tty_struct *tty)
305{
306 speed_t baud = tty_termios_baud_rate(tty->termios);
307
308 if (baud == 38400 && tty->alt_speed) {
309 if (!tty->warned) {
310 printk(KERN_WARNING "Use of setserial/setrocket to "
311 "set SPD_* flags is deprecated\n");
312 tty->warned = 1;
313 }
314 baud = tty->alt_speed;
315 }
316
317 return baud;
318}
319
320EXPORT_SYMBOL(tty_get_baud_rate);
321
af9b897e
AC
322/**
323 * change_termios - update termios values
324 * @tty: tty to update
325 * @new_termios: desired new value
326 *
327 * Perform updates to the termios values set on this terminal. There
328 * is a bit of layering violation here with n_tty in terms of the
329 * internal knowledge of this function.
330 *
331 * Locking: termios_sem
332 */
333
edc6afc5 334static void change_termios(struct tty_struct * tty, struct ktermios * new_termios)
1da177e4
LT
335{
336 int canon_change;
edc6afc5 337 struct ktermios old_termios = *tty->termios;
1da177e4
LT
338 struct tty_ldisc *ld;
339
340 /*
341 * Perform the actual termios internal changes under lock.
342 */
343
344
345 /* FIXME: we need to decide on some locking/ordering semantics
346 for the set_termios notification eventually */
5785c95b 347 mutex_lock(&tty->termios_mutex);
1da177e4
LT
348
349 *tty->termios = *new_termios;
350 unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
351 canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
352 if (canon_change) {
353 memset(&tty->read_flags, 0, sizeof tty->read_flags);
354 tty->canon_head = tty->read_tail;
355 tty->canon_data = 0;
356 tty->erasing = 0;
357 }
358
359
360 if (canon_change && !L_ICANON(tty) && tty->read_cnt)
361 /* Get characters left over from canonical mode. */
362 wake_up_interruptible(&tty->read_wait);
363
364 /* See if packet mode change of state. */
365
366 if (tty->link && tty->link->packet) {
367 int old_flow = ((old_termios.c_iflag & IXON) &&
368 (old_termios.c_cc[VSTOP] == '\023') &&
369 (old_termios.c_cc[VSTART] == '\021'));
370 int new_flow = (I_IXON(tty) &&
371 STOP_CHAR(tty) == '\023' &&
372 START_CHAR(tty) == '\021');
373 if (old_flow != new_flow) {
374 tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
375 if (new_flow)
376 tty->ctrl_status |= TIOCPKT_DOSTOP;
377 else
378 tty->ctrl_status |= TIOCPKT_NOSTOP;
379 wake_up_interruptible(&tty->link->read_wait);
380 }
381 }
382
383 if (tty->driver->set_termios)
384 (*tty->driver->set_termios)(tty, &old_termios);
385
386 ld = tty_ldisc_ref(tty);
387 if (ld != NULL) {
388 if (ld->set_termios)
389 (ld->set_termios)(tty, &old_termios);
390 tty_ldisc_deref(ld);
391 }
5785c95b 392 mutex_unlock(&tty->termios_mutex);
1da177e4
LT
393}
394
af9b897e
AC
395/**
396 * set_termios - set termios values for a tty
397 * @tty: terminal device
398 * @arg: user data
399 * @opt: option information
400 *
401 * Helper function to prepare termios data and run neccessary other
402 * functions before using change_termios to do the actual changes.
403 *
404 * Locking:
405 * Called functions take ldisc and termios_sem locks
406 */
407
1da177e4
LT
408static int set_termios(struct tty_struct * tty, void __user *arg, int opt)
409{
edc6afc5 410 struct ktermios tmp_termios;
1da177e4
LT
411 struct tty_ldisc *ld;
412 int retval = tty_check_change(tty);
413
414 if (retval)
415 return retval;
416
64bb6c5e
AC
417 memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
418
1da177e4 419 if (opt & TERMIOS_TERMIO) {
1da177e4
LT
420 if (user_termio_to_kernel_termios(&tmp_termios,
421 (struct termio __user *)arg))
422 return -EFAULT;
edc6afc5
AC
423#ifdef TCGETS2
424 } else if (opt & TERMIOS_OLD) {
edc6afc5 425 if (user_termios_to_kernel_termios_1(&tmp_termios,
64bb6c5e 426 (struct termios __user *)arg))
edc6afc5 427 return -EFAULT;
1da177e4
LT
428 } else {
429 if (user_termios_to_kernel_termios(&tmp_termios,
64bb6c5e 430 (struct termios2 __user *)arg))
1da177e4
LT
431 return -EFAULT;
432 }
64bb6c5e
AC
433#else
434 } else if (user_termios_to_kernel_termios(&tmp_termios,
435 (struct termios __user *)arg))
436 return -EFAULT;
437#endif
1da177e4 438
edc6afc5
AC
439 /* If old style Bfoo values are used then load c_ispeed/c_ospeed with the real speed
440 so its unconditionally usable */
441 tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
442 tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
443
1da177e4
LT
444 ld = tty_ldisc_ref(tty);
445
446 if (ld != NULL) {
447 if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
448 ld->flush_buffer(tty);
449 tty_ldisc_deref(ld);
450 }
451
452 if (opt & TERMIOS_WAIT) {
453 tty_wait_until_sent(tty, 0);
454 if (signal_pending(current))
455 return -EINTR;
456 }
457
458 change_termios(tty, &tmp_termios);
459 return 0;
460}
461
462static int get_termio(struct tty_struct * tty, struct termio __user * termio)
463{
464 if (kernel_termios_to_user_termio(termio, tty->termios))
465 return -EFAULT;
466 return 0;
467}
468
469static unsigned long inq_canon(struct tty_struct * tty)
470{
471 int nr, head, tail;
472
473 if (!tty->canon_data || !tty->read_buf)
474 return 0;
475 head = tty->canon_head;
476 tail = tty->read_tail;
477 nr = (head - tail) & (N_TTY_BUF_SIZE-1);
478 /* Skip EOF-chars.. */
479 while (head != tail) {
480 if (test_bit(tail, tty->read_flags) &&
481 tty->read_buf[tail] == __DISABLED_CHAR)
482 nr--;
483 tail = (tail+1) & (N_TTY_BUF_SIZE-1);
484 }
485 return nr;
486}
487
488#ifdef TIOCGETP
489/*
490 * These are deprecated, but there is limited support..
491 *
492 * The "sg_flags" translation is a joke..
493 */
494static int get_sgflags(struct tty_struct * tty)
495{
496 int flags = 0;
497
498 if (!(tty->termios->c_lflag & ICANON)) {
499 if (tty->termios->c_lflag & ISIG)
500 flags |= 0x02; /* cbreak */
501 else
502 flags |= 0x20; /* raw */
503 }
504 if (tty->termios->c_lflag & ECHO)
505 flags |= 0x08; /* echo */
506 if (tty->termios->c_oflag & OPOST)
507 if (tty->termios->c_oflag & ONLCR)
508 flags |= 0x10; /* crmod */
509 return flags;
510}
511
512static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
513{
514 struct sgttyb tmp;
515
5785c95b 516 mutex_lock(&tty->termios_mutex);
606d099c
AC
517 tmp.sg_ispeed = tty->termios->c_ispeed;
518 tmp.sg_ospeed = tty->termios->c_ospeed;
1da177e4
LT
519 tmp.sg_erase = tty->termios->c_cc[VERASE];
520 tmp.sg_kill = tty->termios->c_cc[VKILL];
521 tmp.sg_flags = get_sgflags(tty);
5785c95b 522 mutex_unlock(&tty->termios_mutex);
1da177e4
LT
523
524 return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
525}
526
edc6afc5 527static void set_sgflags(struct ktermios * termios, int flags)
1da177e4
LT
528{
529 termios->c_iflag = ICRNL | IXON;
530 termios->c_oflag = 0;
531 termios->c_lflag = ISIG | ICANON;
532 if (flags & 0x02) { /* cbreak */
533 termios->c_iflag = 0;
534 termios->c_lflag &= ~ICANON;
535 }
536 if (flags & 0x08) { /* echo */
537 termios->c_lflag |= ECHO | ECHOE | ECHOK |
538 ECHOCTL | ECHOKE | IEXTEN;
539 }
540 if (flags & 0x10) { /* crmod */
541 termios->c_oflag |= OPOST | ONLCR;
542 }
543 if (flags & 0x20) { /* raw */
544 termios->c_iflag = 0;
545 termios->c_lflag &= ~(ISIG | ICANON);
546 }
547 if (!(termios->c_lflag & ICANON)) {
548 termios->c_cc[VMIN] = 1;
549 termios->c_cc[VTIME] = 0;
550 }
551}
552
af9b897e
AC
553/**
554 * set_sgttyb - set legacy terminal values
555 * @tty: tty structure
556 * @sgttyb: pointer to old style terminal structure
557 *
558 * Updates a terminal from the legacy BSD style terminal information
559 * structure.
560 *
561 * Locking: termios_sem
562 */
563
1da177e4
LT
564static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
565{
566 int retval;
567 struct sgttyb tmp;
edc6afc5 568 struct ktermios termios;
1da177e4
LT
569
570 retval = tty_check_change(tty);
571 if (retval)
572 return retval;
573
574 if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
575 return -EFAULT;
576
5785c95b 577 mutex_lock(&tty->termios_mutex);
1da177e4
LT
578 termios = *tty->termios;
579 termios.c_cc[VERASE] = tmp.sg_erase;
580 termios.c_cc[VKILL] = tmp.sg_kill;
581 set_sgflags(&termios, tmp.sg_flags);
edc6afc5
AC
582 /* Try and encode into Bfoo format */
583#ifdef BOTHER
584 tty_termios_encode_baud_rate(&termios, termios.c_ispeed, termios.c_ospeed);
585#endif
5785c95b 586 mutex_unlock(&tty->termios_mutex);
1da177e4
LT
587 change_termios(tty, &termios);
588 return 0;
589}
590#endif
591
592#ifdef TIOCGETC
593static int get_tchars(struct tty_struct * tty, struct tchars __user * tchars)
594{
595 struct tchars tmp;
596
597 tmp.t_intrc = tty->termios->c_cc[VINTR];
598 tmp.t_quitc = tty->termios->c_cc[VQUIT];
599 tmp.t_startc = tty->termios->c_cc[VSTART];
600 tmp.t_stopc = tty->termios->c_cc[VSTOP];
601 tmp.t_eofc = tty->termios->c_cc[VEOF];
602 tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
603 return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
604}
605
606static int set_tchars(struct tty_struct * tty, struct tchars __user * tchars)
607{
608 struct tchars tmp;
609
610 if (copy_from_user(&tmp, tchars, sizeof(tmp)))
611 return -EFAULT;
612 tty->termios->c_cc[VINTR] = tmp.t_intrc;
613 tty->termios->c_cc[VQUIT] = tmp.t_quitc;
614 tty->termios->c_cc[VSTART] = tmp.t_startc;
615 tty->termios->c_cc[VSTOP] = tmp.t_stopc;
616 tty->termios->c_cc[VEOF] = tmp.t_eofc;
617 tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
618 return 0;
619}
620#endif
621
622#ifdef TIOCGLTC
623static int get_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars)
624{
625 struct ltchars tmp;
626
627 tmp.t_suspc = tty->termios->c_cc[VSUSP];
628 tmp.t_dsuspc = tty->termios->c_cc[VSUSP]; /* what is dsuspc anyway? */
629 tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
630 tmp.t_flushc = tty->termios->c_cc[VEOL2]; /* what is flushc anyway? */
631 tmp.t_werasc = tty->termios->c_cc[VWERASE];
632 tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
633 return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
634}
635
636static int set_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars)
637{
638 struct ltchars tmp;
639
640 if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
641 return -EFAULT;
642
643 tty->termios->c_cc[VSUSP] = tmp.t_suspc;
644 tty->termios->c_cc[VEOL2] = tmp.t_dsuspc; /* what is dsuspc anyway? */
645 tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
646 tty->termios->c_cc[VEOL2] = tmp.t_flushc; /* what is flushc anyway? */
647 tty->termios->c_cc[VWERASE] = tmp.t_werasc;
648 tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
649 return 0;
650}
651#endif
652
af9b897e
AC
653/**
654 * send_prio_char - send priority character
655 *
656 * Send a high priority character to the tty even if stopped
657 *
5f412b24 658 * Locking: none for xchar method, write ordering for write method.
1da177e4 659 */
af9b897e 660
5f412b24 661static int send_prio_char(struct tty_struct *tty, char ch)
1da177e4
LT
662{
663 int was_stopped = tty->stopped;
664
665 if (tty->driver->send_xchar) {
666 tty->driver->send_xchar(tty, ch);
5f412b24 667 return 0;
1da177e4 668 }
5f412b24
AC
669
670 if (mutex_lock_interruptible(&tty->atomic_write_lock))
671 return -ERESTARTSYS;
672
1da177e4
LT
673 if (was_stopped)
674 start_tty(tty);
675 tty->driver->write(tty, &ch, 1);
676 if (was_stopped)
677 stop_tty(tty);
5f412b24
AC
678 mutex_unlock(&tty->atomic_write_lock);
679 return 0;
1da177e4
LT
680}
681
682int n_tty_ioctl(struct tty_struct * tty, struct file * file,
683 unsigned int cmd, unsigned long arg)
684{
685 struct tty_struct * real_tty;
686 void __user *p = (void __user *)arg;
687 int retval;
688 struct tty_ldisc *ld;
689
690 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
691 tty->driver->subtype == PTY_TYPE_MASTER)
692 real_tty = tty->link;
693 else
694 real_tty = tty;
695
696 switch (cmd) {
697#ifdef TIOCGETP
698 case TIOCGETP:
699 return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
700 case TIOCSETP:
701 case TIOCSETN:
702 return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
703#endif
704#ifdef TIOCGETC
705 case TIOCGETC:
706 return get_tchars(real_tty, p);
707 case TIOCSETC:
708 return set_tchars(real_tty, p);
709#endif
710#ifdef TIOCGLTC
711 case TIOCGLTC:
712 return get_ltchars(real_tty, p);
713 case TIOCSLTC:
714 return set_ltchars(real_tty, p);
715#endif
edc6afc5
AC
716 case TCSETSF:
717 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
718 case TCSETSW:
719 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
720 case TCSETS:
721 return set_termios(real_tty, p, TERMIOS_OLD);
722#ifndef TCGETS2
1da177e4
LT
723 case TCGETS:
724 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
725 return -EFAULT;
726 return 0;
edc6afc5
AC
727#else
728 case TCGETS:
64bb6c5e 729 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios))
edc6afc5
AC
730 return -EFAULT;
731 return 0;
732 case TCGETS2:
64bb6c5e 733 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios))
edc6afc5
AC
734 return -EFAULT;
735 return 0;
736 case TCSETSF2:
1da177e4 737 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT);
edc6afc5 738 case TCSETSW2:
1da177e4 739 return set_termios(real_tty, p, TERMIOS_WAIT);
edc6afc5 740 case TCSETS2:
1da177e4 741 return set_termios(real_tty, p, 0);
edc6afc5 742#endif
1da177e4
LT
743 case TCGETA:
744 return get_termio(real_tty, p);
745 case TCSETAF:
746 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
747 case TCSETAW:
748 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
749 case TCSETA:
750 return set_termios(real_tty, p, TERMIOS_TERMIO);
751 case TCXONC:
752 retval = tty_check_change(tty);
753 if (retval)
754 return retval;
755 switch (arg) {
756 case TCOOFF:
757 if (!tty->flow_stopped) {
758 tty->flow_stopped = 1;
759 stop_tty(tty);
760 }
761 break;
762 case TCOON:
763 if (tty->flow_stopped) {
764 tty->flow_stopped = 0;
765 start_tty(tty);
766 }
767 break;
768 case TCIOFF:
769 if (STOP_CHAR(tty) != __DISABLED_CHAR)
5f412b24 770 return send_prio_char(tty, STOP_CHAR(tty));
1da177e4
LT
771 break;
772 case TCION:
773 if (START_CHAR(tty) != __DISABLED_CHAR)
5f412b24 774 return send_prio_char(tty, START_CHAR(tty));
1da177e4
LT
775 break;
776 default:
777 return -EINVAL;
778 }
779 return 0;
780 case TCFLSH:
781 retval = tty_check_change(tty);
782 if (retval)
783 return retval;
784
785 ld = tty_ldisc_ref(tty);
786 switch (arg) {
787 case TCIFLUSH:
69f63c5c 788 if (ld && ld->flush_buffer)
1da177e4
LT
789 ld->flush_buffer(tty);
790 break;
791 case TCIOFLUSH:
69f63c5c 792 if (ld && ld->flush_buffer)
1da177e4
LT
793 ld->flush_buffer(tty);
794 /* fall through */
795 case TCOFLUSH:
796 if (tty->driver->flush_buffer)
797 tty->driver->flush_buffer(tty);
798 break;
799 default:
800 tty_ldisc_deref(ld);
801 return -EINVAL;
802 }
803 tty_ldisc_deref(ld);
804 return 0;
805 case TIOCOUTQ:
806 return put_user(tty->driver->chars_in_buffer ?
807 tty->driver->chars_in_buffer(tty) : 0,
808 (int __user *) arg);
809 case TIOCINQ:
810 retval = tty->read_cnt;
811 if (L_ICANON(tty))
812 retval = inq_canon(tty);
813 return put_user(retval, (unsigned int __user *) arg);
814 case TIOCGLCKTRMIOS:
815 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
816 return -EFAULT;
817 return 0;
818
819 case TIOCSLCKTRMIOS:
820 if (!capable(CAP_SYS_ADMIN))
821 return -EPERM;
822 if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg))
823 return -EFAULT;
824 return 0;
825
826 case TIOCPKT:
827 {
828 int pktmode;
829
830 if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
831 tty->driver->subtype != PTY_TYPE_MASTER)
832 return -ENOTTY;
833 if (get_user(pktmode, (int __user *) arg))
834 return -EFAULT;
835 if (pktmode) {
836 if (!tty->packet) {
837 tty->packet = 1;
838 tty->link->ctrl_status = 0;
839 }
840 } else
841 tty->packet = 0;
842 return 0;
843 }
844 case TIOCGSOFTCAR:
845 return put_user(C_CLOCAL(tty) ? 1 : 0, (int __user *)arg);
846 case TIOCSSOFTCAR:
847 if (get_user(arg, (unsigned int __user *) arg))
848 return -EFAULT;
5785c95b 849 mutex_lock(&tty->termios_mutex);
1da177e4
LT
850 tty->termios->c_cflag =
851 ((tty->termios->c_cflag & ~CLOCAL) |
852 (arg ? CLOCAL : 0));
5785c95b 853 mutex_unlock(&tty->termios_mutex);
1da177e4
LT
854 return 0;
855 default:
856 return -ENOIOCTLCMD;
857 }
858}
859
860EXPORT_SYMBOL(n_tty_ioctl);