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