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