]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/char/tty_ioctl.c
[XFS] kill usesless IHOLD calls in xfs_remove and xfs_rmdir
[linux-2.6-omap-h63xx.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
399         /*
400          *      Perform the actual termios internal changes under lock.
401          */
402
403
404         /* FIXME: we need to decide on some locking/ordering semantics
405            for the set_termios notification eventually */
406         mutex_lock(&tty->termios_mutex);
407
408         *tty->termios = *new_termios;
409         unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
410         canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
411         if (canon_change) {
412                 memset(&tty->read_flags, 0, sizeof tty->read_flags);
413                 tty->canon_head = tty->read_tail;
414                 tty->canon_data = 0;
415                 tty->erasing = 0;
416         }
417
418         /* This bit should be in the ldisc code */
419         if (canon_change && !L_ICANON(tty) && tty->read_cnt)
420                 /* Get characters left over from canonical mode. */
421                 wake_up_interruptible(&tty->read_wait);
422
423         /* See if packet mode change of state. */
424         if (tty->link && tty->link->packet) {
425                 int old_flow = ((old_termios.c_iflag & IXON) &&
426                                 (old_termios.c_cc[VSTOP] == '\023') &&
427                                 (old_termios.c_cc[VSTART] == '\021'));
428                 int new_flow = (I_IXON(tty) &&
429                                 STOP_CHAR(tty) == '\023' &&
430                                 START_CHAR(tty) == '\021');
431                 if (old_flow != new_flow) {
432                         tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
433                         if (new_flow)
434                                 tty->ctrl_status |= TIOCPKT_DOSTOP;
435                         else
436                                 tty->ctrl_status |= TIOCPKT_NOSTOP;
437                         wake_up_interruptible(&tty->link->read_wait);
438                 }
439         }
440
441         if (tty->driver->set_termios)
442                 (*tty->driver->set_termios)(tty, &old_termios);
443         else
444                 tty_termios_copy_hw(tty->termios, &old_termios);
445
446         ld = tty_ldisc_ref(tty);
447         if (ld != NULL) {
448                 if (ld->set_termios)
449                         (ld->set_termios)(tty, &old_termios);
450                 tty_ldisc_deref(ld);
451         }
452         mutex_unlock(&tty->termios_mutex);
453 }
454
455 /**
456  *      set_termios             -       set termios values for a tty
457  *      @tty: terminal device
458  *      @arg: user data
459  *      @opt: option information
460  *
461  *      Helper function to prepare termios data and run necessary other
462  *      functions before using change_termios to do the actual changes.
463  *
464  *      Locking:
465  *              Called functions take ldisc and termios_sem locks
466  */
467
468 static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
469 {
470         struct ktermios tmp_termios;
471         struct tty_ldisc *ld;
472         int retval = tty_check_change(tty);
473
474         if (retval)
475                 return retval;
476
477         memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
478
479         if (opt & TERMIOS_TERMIO) {
480                 if (user_termio_to_kernel_termios(&tmp_termios,
481                                                 (struct termio __user *)arg))
482                         return -EFAULT;
483 #ifdef TCGETS2
484         } else if (opt & TERMIOS_OLD) {
485                 if (user_termios_to_kernel_termios_1(&tmp_termios,
486                                                 (struct termios __user *)arg))
487                         return -EFAULT;
488         } else {
489                 if (user_termios_to_kernel_termios(&tmp_termios,
490                                                 (struct termios2 __user *)arg))
491                         return -EFAULT;
492         }
493 #else
494         } else if (user_termios_to_kernel_termios(&tmp_termios,
495                                         (struct termios __user *)arg))
496                 return -EFAULT;
497 #endif
498
499         /* If old style Bfoo values are used then load c_ispeed/c_ospeed
500          * with the real speed so its unconditionally usable */
501         tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
502         tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
503
504         ld = tty_ldisc_ref(tty);
505
506         if (ld != NULL) {
507                 if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
508                         ld->flush_buffer(tty);
509                 tty_ldisc_deref(ld);
510         }
511
512         if (opt & TERMIOS_WAIT) {
513                 tty_wait_until_sent(tty, 0);
514                 if (signal_pending(current))
515                         return -EINTR;
516         }
517
518         change_termios(tty, &tmp_termios);
519
520         /* FIXME: Arguably if tmp_termios == tty->termios AND the
521            actual requested termios was not tmp_termios then we may
522            want to return an error as no user requested change has
523            succeeded */
524         return 0;
525 }
526
527 static int get_termio(struct tty_struct *tty, struct termio __user *termio)
528 {
529         if (kernel_termios_to_user_termio(termio, tty->termios))
530                 return -EFAULT;
531         return 0;
532 }
533
534 static unsigned long inq_canon(struct tty_struct *tty)
535 {
536         int nr, head, tail;
537
538         if (!tty->canon_data || !tty->read_buf)
539                 return 0;
540         head = tty->canon_head;
541         tail = tty->read_tail;
542         nr = (head - tail) & (N_TTY_BUF_SIZE-1);
543         /* Skip EOF-chars.. */
544         while (head != tail) {
545                 if (test_bit(tail, tty->read_flags) &&
546                     tty->read_buf[tail] == __DISABLED_CHAR)
547                         nr--;
548                 tail = (tail+1) & (N_TTY_BUF_SIZE-1);
549         }
550         return nr;
551 }
552
553 #ifdef TIOCGETP
554 /*
555  * These are deprecated, but there is limited support..
556  *
557  * The "sg_flags" translation is a joke..
558  */
559 static int get_sgflags(struct tty_struct *tty)
560 {
561         int flags = 0;
562
563         if (!(tty->termios->c_lflag & ICANON)) {
564                 if (tty->termios->c_lflag & ISIG)
565                         flags |= 0x02;          /* cbreak */
566                 else
567                         flags |= 0x20;          /* raw */
568         }
569         if (tty->termios->c_lflag & ECHO)
570                 flags |= 0x08;                  /* echo */
571         if (tty->termios->c_oflag & OPOST)
572                 if (tty->termios->c_oflag & ONLCR)
573                         flags |= 0x10;          /* crmod */
574         return flags;
575 }
576
577 static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
578 {
579         struct sgttyb tmp;
580
581         mutex_lock(&tty->termios_mutex);
582         tmp.sg_ispeed = tty->termios->c_ispeed;
583         tmp.sg_ospeed = tty->termios->c_ospeed;
584         tmp.sg_erase = tty->termios->c_cc[VERASE];
585         tmp.sg_kill = tty->termios->c_cc[VKILL];
586         tmp.sg_flags = get_sgflags(tty);
587         mutex_unlock(&tty->termios_mutex);
588
589         return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
590 }
591
592 static void set_sgflags(struct ktermios *termios, int flags)
593 {
594         termios->c_iflag = ICRNL | IXON;
595         termios->c_oflag = 0;
596         termios->c_lflag = ISIG | ICANON;
597         if (flags & 0x02) {     /* cbreak */
598                 termios->c_iflag = 0;
599                 termios->c_lflag &= ~ICANON;
600         }
601         if (flags & 0x08) {             /* echo */
602                 termios->c_lflag |= ECHO | ECHOE | ECHOK |
603                                     ECHOCTL | ECHOKE | IEXTEN;
604         }
605         if (flags & 0x10) {             /* crmod */
606                 termios->c_oflag |= OPOST | ONLCR;
607         }
608         if (flags & 0x20) {     /* raw */
609                 termios->c_iflag = 0;
610                 termios->c_lflag &= ~(ISIG | ICANON);
611         }
612         if (!(termios->c_lflag & ICANON)) {
613                 termios->c_cc[VMIN] = 1;
614                 termios->c_cc[VTIME] = 0;
615         }
616 }
617
618 /**
619  *      set_sgttyb              -       set legacy terminal values
620  *      @tty: tty structure
621  *      @sgttyb: pointer to old style terminal structure
622  *
623  *      Updates a terminal from the legacy BSD style terminal information
624  *      structure.
625  *
626  *      Locking: termios_sem
627  */
628
629 static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
630 {
631         int retval;
632         struct sgttyb tmp;
633         struct ktermios termios;
634
635         retval = tty_check_change(tty);
636         if (retval)
637                 return retval;
638
639         if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
640                 return -EFAULT;
641
642         mutex_lock(&tty->termios_mutex);
643         termios = *tty->termios;
644         termios.c_cc[VERASE] = tmp.sg_erase;
645         termios.c_cc[VKILL] = tmp.sg_kill;
646         set_sgflags(&termios, tmp.sg_flags);
647         /* Try and encode into Bfoo format */
648 #ifdef BOTHER
649         tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
650                                                 termios.c_ospeed);
651 #endif
652         mutex_unlock(&tty->termios_mutex);
653         change_termios(tty, &termios);
654         return 0;
655 }
656 #endif
657
658 #ifdef TIOCGETC
659 static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
660 {
661         struct tchars tmp;
662
663         tmp.t_intrc = tty->termios->c_cc[VINTR];
664         tmp.t_quitc = tty->termios->c_cc[VQUIT];
665         tmp.t_startc = tty->termios->c_cc[VSTART];
666         tmp.t_stopc = tty->termios->c_cc[VSTOP];
667         tmp.t_eofc = tty->termios->c_cc[VEOF];
668         tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
669         return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
670 }
671
672 static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
673 {
674         struct tchars tmp;
675
676         if (copy_from_user(&tmp, tchars, sizeof(tmp)))
677                 return -EFAULT;
678         tty->termios->c_cc[VINTR] = tmp.t_intrc;
679         tty->termios->c_cc[VQUIT] = tmp.t_quitc;
680         tty->termios->c_cc[VSTART] = tmp.t_startc;
681         tty->termios->c_cc[VSTOP] = tmp.t_stopc;
682         tty->termios->c_cc[VEOF] = tmp.t_eofc;
683         tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
684         return 0;
685 }
686 #endif
687
688 #ifdef TIOCGLTC
689 static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
690 {
691         struct ltchars tmp;
692
693         tmp.t_suspc = tty->termios->c_cc[VSUSP];
694         /* what is dsuspc anyway? */
695         tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
696         tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
697         /* what is flushc anyway? */
698         tmp.t_flushc = tty->termios->c_cc[VEOL2];
699         tmp.t_werasc = tty->termios->c_cc[VWERASE];
700         tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
701         return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
702 }
703
704 static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
705 {
706         struct ltchars tmp;
707
708         if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
709                 return -EFAULT;
710
711         tty->termios->c_cc[VSUSP] = tmp.t_suspc;
712         /* what is dsuspc anyway? */
713         tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
714         tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
715         /* what is flushc anyway? */
716         tty->termios->c_cc[VEOL2] = tmp.t_flushc;
717         tty->termios->c_cc[VWERASE] = tmp.t_werasc;
718         tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
719         return 0;
720 }
721 #endif
722
723 /**
724  *      send_prio_char          -       send priority character
725  *
726  *      Send a high priority character to the tty even if stopped
727  *
728  *      Locking: none for xchar method, write ordering for write method.
729  */
730
731 static int send_prio_char(struct tty_struct *tty, char ch)
732 {
733         int     was_stopped = tty->stopped;
734
735         if (tty->driver->send_xchar) {
736                 tty->driver->send_xchar(tty, ch);
737                 return 0;
738         }
739
740         if (tty_write_lock(tty, 0) < 0)
741                 return -ERESTARTSYS;
742
743         if (was_stopped)
744                 start_tty(tty);
745         tty->driver->write(tty, &ch, 1);
746         if (was_stopped)
747                 stop_tty(tty);
748         tty_write_unlock(tty);
749         return 0;
750 }
751
752 /**
753  *      tty_mode_ioctl          -       mode related ioctls
754  *      @tty: tty for the ioctl
755  *      @file: file pointer for the tty
756  *      @cmd: command
757  *      @arg: ioctl argument
758  *
759  *      Perform non line discipline specific mode control ioctls. This
760  *      is designed to be called by line disciplines to ensure they provide
761  *      consistent mode setting.
762  */
763
764 int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
765                         unsigned int cmd, unsigned long arg)
766 {
767         struct tty_struct *real_tty;
768         void __user *p = (void __user *)arg;
769
770         if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
771             tty->driver->subtype == PTY_TYPE_MASTER)
772                 real_tty = tty->link;
773         else
774                 real_tty = tty;
775
776         switch (cmd) {
777 #ifdef TIOCGETP
778         case TIOCGETP:
779                 return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
780         case TIOCSETP:
781         case TIOCSETN:
782                 return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
783 #endif
784 #ifdef TIOCGETC
785         case TIOCGETC:
786                 return get_tchars(real_tty, p);
787         case TIOCSETC:
788                 return set_tchars(real_tty, p);
789 #endif
790 #ifdef TIOCGLTC
791         case TIOCGLTC:
792                 return get_ltchars(real_tty, p);
793         case TIOCSLTC:
794                 return set_ltchars(real_tty, p);
795 #endif
796         case TCSETSF:
797                 return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
798         case TCSETSW:
799                 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
800         case TCSETS:
801                 return set_termios(real_tty, p, TERMIOS_OLD);
802 #ifndef TCGETS2
803         case TCGETS:
804                 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
805                         return -EFAULT;
806                 return 0;
807 #else
808         case TCGETS:
809                 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios))
810                         return -EFAULT;
811                 return 0;
812         case TCGETS2:
813                 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios))
814                         return -EFAULT;
815                 return 0;
816         case TCSETSF2:
817                 return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT);
818         case TCSETSW2:
819                 return set_termios(real_tty, p, TERMIOS_WAIT);
820         case TCSETS2:
821                 return set_termios(real_tty, p, 0);
822 #endif
823         case TCGETA:
824                 return get_termio(real_tty, p);
825         case TCSETAF:
826                 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
827         case TCSETAW:
828                 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
829         case TCSETA:
830                 return set_termios(real_tty, p, TERMIOS_TERMIO);
831 #ifndef TCGETS2
832         case TIOCGLCKTRMIOS:
833                 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
834                         return -EFAULT;
835                 return 0;
836         case TIOCSLCKTRMIOS:
837                 if (!capable(CAP_SYS_ADMIN))
838                         return -EPERM;
839                 if (user_termios_to_kernel_termios(real_tty->termios_locked,
840                                                (struct termios __user *) arg))
841                         return -EFAULT;
842                 return 0;
843 #else
844         case TIOCGLCKTRMIOS:
845                 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
846                         return -EFAULT;
847                 return 0;
848         case TIOCSLCKTRMIOS:
849                 if (!capable(CAP_SYS_ADMIN))
850                         return -EPERM;
851                 if (user_termios_to_kernel_termios_1(real_tty->termios_locked,
852                                                (struct termios __user *) arg))
853                         return -EFAULT;
854                         return 0;
855 #endif
856         case TIOCGSOFTCAR:
857                 return put_user(C_CLOCAL(tty) ? 1 : 0,
858                                                 (int __user *)arg);
859         case TIOCSSOFTCAR:
860                 if (get_user(arg, (unsigned int __user *) arg))
861                         return -EFAULT;
862                 mutex_lock(&tty->termios_mutex);
863                 tty->termios->c_cflag =
864                         ((tty->termios->c_cflag & ~CLOCAL) |
865                          (arg ? CLOCAL : 0));
866                 mutex_unlock(&tty->termios_mutex);
867                 return 0;
868         default:
869                 return -ENOIOCTLCMD;
870         }
871 }
872 EXPORT_SYMBOL_GPL(tty_mode_ioctl);
873
874 int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
875 {
876         struct tty_ldisc *ld;
877         int retval = tty_check_change(tty);
878         if (retval)
879                 return retval;
880
881         ld = tty_ldisc_ref(tty);
882         switch (arg) {
883         case TCIFLUSH:
884                 if (ld && ld->flush_buffer)
885                         ld->flush_buffer(tty);
886                 break;
887         case TCIOFLUSH:
888                 if (ld && ld->flush_buffer)
889                         ld->flush_buffer(tty);
890                 /* fall through */
891         case TCOFLUSH:
892                 if (tty->driver->flush_buffer)
893                         tty->driver->flush_buffer(tty);
894                 break;
895         default:
896                 tty_ldisc_deref(ld);
897                 return -EINVAL;
898         }
899         tty_ldisc_deref(ld);
900         return 0;
901 }
902 EXPORT_SYMBOL_GPL(tty_perform_flush);
903
904 int n_tty_ioctl(struct tty_struct *tty, struct file *file,
905                        unsigned int cmd, unsigned long arg)
906 {
907         struct tty_struct *real_tty;
908         int retval;
909
910         if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
911             tty->driver->subtype == PTY_TYPE_MASTER)
912                 real_tty = tty->link;
913         else
914                 real_tty = tty;
915
916         switch (cmd) {
917         case TCXONC:
918                 retval = tty_check_change(tty);
919                 if (retval)
920                         return retval;
921                 switch (arg) {
922                 case TCOOFF:
923                         if (!tty->flow_stopped) {
924                                 tty->flow_stopped = 1;
925                                 stop_tty(tty);
926                         }
927                         break;
928                 case TCOON:
929                         if (tty->flow_stopped) {
930                                 tty->flow_stopped = 0;
931                                 start_tty(tty);
932                         }
933                         break;
934                 case TCIOFF:
935                         if (STOP_CHAR(tty) != __DISABLED_CHAR)
936                                 return send_prio_char(tty, STOP_CHAR(tty));
937                         break;
938                 case TCION:
939                         if (START_CHAR(tty) != __DISABLED_CHAR)
940                                 return send_prio_char(tty, START_CHAR(tty));
941                         break;
942                 default:
943                         return -EINVAL;
944                 }
945                 return 0;
946         case TCFLSH:
947                 return tty_perform_flush(tty, arg);
948         case TIOCOUTQ:
949                 return put_user(tty->driver->chars_in_buffer ?
950                                 tty->driver->chars_in_buffer(tty) : 0,
951                                 (int __user *) arg);
952         case TIOCINQ:
953                 retval = tty->read_cnt;
954                 if (L_ICANON(tty))
955                         retval = inq_canon(tty);
956                 return put_user(retval, (unsigned int __user *) arg);
957         case TIOCPKT:
958         {
959                 int pktmode;
960
961                 if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
962                     tty->driver->subtype != PTY_TYPE_MASTER)
963                         return -ENOTTY;
964                 if (get_user(pktmode, (int __user *) arg))
965                         return -EFAULT;
966                 if (pktmode) {
967                         if (!tty->packet) {
968                                 tty->packet = 1;
969                                 tty->link->ctrl_status = 0;
970                         }
971                 } else
972                         tty->packet = 0;
973                 return 0;
974         }
975         default:
976                 /* Try the mode commands */
977                 return tty_mode_ioctl(tty, file, cmd, arg);
978         }
979 }
980 EXPORT_SYMBOL(n_tty_ioctl);