Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
[cascardo/linux.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  *      Locking: termios_rwsem
532  */
533
534 int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
535 {
536         struct ktermios old_termios;
537         struct tty_ldisc *ld;
538         unsigned long flags;
539
540         /*
541          *      Perform the actual termios internal changes under lock.
542          */
543
544
545         /* FIXME: we need to decide on some locking/ordering semantics
546            for the set_termios notification eventually */
547         down_write(&tty->termios_rwsem);
548         old_termios = tty->termios;
549         tty->termios = *new_termios;
550         unset_locked_termios(&tty->termios, &old_termios, &tty->termios_locked);
551
552         /* See if packet mode change of state. */
553         if (tty->link && tty->link->packet) {
554                 int extproc = (old_termios.c_lflag & EXTPROC) |
555                                 (tty->termios.c_lflag & EXTPROC);
556                 int old_flow = ((old_termios.c_iflag & IXON) &&
557                                 (old_termios.c_cc[VSTOP] == '\023') &&
558                                 (old_termios.c_cc[VSTART] == '\021'));
559                 int new_flow = (I_IXON(tty) &&
560                                 STOP_CHAR(tty) == '\023' &&
561                                 START_CHAR(tty) == '\021');
562                 if ((old_flow != new_flow) || extproc) {
563                         spin_lock_irqsave(&tty->ctrl_lock, flags);
564                         if (old_flow != new_flow) {
565                                 tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
566                                 if (new_flow)
567                                         tty->ctrl_status |= TIOCPKT_DOSTOP;
568                                 else
569                                         tty->ctrl_status |= TIOCPKT_NOSTOP;
570                         }
571                         if (extproc)
572                                 tty->ctrl_status |= TIOCPKT_IOCTL;
573                         spin_unlock_irqrestore(&tty->ctrl_lock, flags);
574                         wake_up_interruptible(&tty->link->read_wait);
575                 }
576         }
577
578         if (tty->ops->set_termios)
579                 (*tty->ops->set_termios)(tty, &old_termios);
580         else
581                 tty_termios_copy_hw(&tty->termios, &old_termios);
582
583         ld = tty_ldisc_ref(tty);
584         if (ld != NULL) {
585                 if (ld->ops->set_termios)
586                         (ld->ops->set_termios)(tty, &old_termios);
587                 tty_ldisc_deref(ld);
588         }
589         up_write(&tty->termios_rwsem);
590         return 0;
591 }
592 EXPORT_SYMBOL_GPL(tty_set_termios);
593
594 /**
595  *      set_termios             -       set termios values for a tty
596  *      @tty: terminal device
597  *      @arg: user data
598  *      @opt: option information
599  *
600  *      Helper function to prepare termios data and run necessary other
601  *      functions before using tty_set_termios to do the actual changes.
602  *
603  *      Locking:
604  *              Called functions take ldisc and termios_rwsem locks
605  */
606
607 static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
608 {
609         struct ktermios tmp_termios;
610         struct tty_ldisc *ld;
611         int retval = tty_check_change(tty);
612
613         if (retval)
614                 return retval;
615
616         down_read(&tty->termios_rwsem);
617         tmp_termios = tty->termios;
618         up_read(&tty->termios_rwsem);
619
620         if (opt & TERMIOS_TERMIO) {
621                 if (user_termio_to_kernel_termios(&tmp_termios,
622                                                 (struct termio __user *)arg))
623                         return -EFAULT;
624 #ifdef TCGETS2
625         } else if (opt & TERMIOS_OLD) {
626                 if (user_termios_to_kernel_termios_1(&tmp_termios,
627                                                 (struct termios __user *)arg))
628                         return -EFAULT;
629         } else {
630                 if (user_termios_to_kernel_termios(&tmp_termios,
631                                                 (struct termios2 __user *)arg))
632                         return -EFAULT;
633         }
634 #else
635         } else if (user_termios_to_kernel_termios(&tmp_termios,
636                                         (struct termios __user *)arg))
637                 return -EFAULT;
638 #endif
639
640         /* If old style Bfoo values are used then load c_ispeed/c_ospeed
641          * with the real speed so its unconditionally usable */
642         tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
643         tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
644
645         ld = tty_ldisc_ref(tty);
646
647         if (ld != NULL) {
648                 if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
649                         ld->ops->flush_buffer(tty);
650                 tty_ldisc_deref(ld);
651         }
652
653         if (opt & TERMIOS_WAIT) {
654                 tty_wait_until_sent(tty, 0);
655                 if (signal_pending(current))
656                         return -ERESTARTSYS;
657         }
658
659         tty_set_termios(tty, &tmp_termios);
660
661         /* FIXME: Arguably if tmp_termios == tty->termios AND the
662            actual requested termios was not tmp_termios then we may
663            want to return an error as no user requested change has
664            succeeded */
665         return 0;
666 }
667
668 static void copy_termios(struct tty_struct *tty, struct ktermios *kterm)
669 {
670         down_read(&tty->termios_rwsem);
671         *kterm = tty->termios;
672         up_read(&tty->termios_rwsem);
673 }
674
675 static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm)
676 {
677         down_read(&tty->termios_rwsem);
678         *kterm = tty->termios_locked;
679         up_read(&tty->termios_rwsem);
680 }
681
682 static int get_termio(struct tty_struct *tty, struct termio __user *termio)
683 {
684         struct ktermios kterm;
685         copy_termios(tty, &kterm);
686         if (kernel_termios_to_user_termio(termio, &kterm))
687                 return -EFAULT;
688         return 0;
689 }
690
691
692 #ifdef TCGETX
693
694 /**
695  *      set_termiox     -       set termiox fields if possible
696  *      @tty: terminal
697  *      @arg: termiox structure from user
698  *      @opt: option flags for ioctl type
699  *
700  *      Implement the device calling points for the SYS5 termiox ioctl
701  *      interface in Linux
702  */
703
704 static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
705 {
706         struct termiox tnew;
707         struct tty_ldisc *ld;
708
709         if (tty->termiox == NULL)
710                 return -EINVAL;
711         if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
712                 return -EFAULT;
713
714         ld = tty_ldisc_ref(tty);
715         if (ld != NULL) {
716                 if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
717                         ld->ops->flush_buffer(tty);
718                 tty_ldisc_deref(ld);
719         }
720         if (opt & TERMIOS_WAIT) {
721                 tty_wait_until_sent(tty, 0);
722                 if (signal_pending(current))
723                         return -ERESTARTSYS;
724         }
725
726         down_write(&tty->termios_rwsem);
727         if (tty->ops->set_termiox)
728                 tty->ops->set_termiox(tty, &tnew);
729         up_write(&tty->termios_rwsem);
730         return 0;
731 }
732
733 #endif
734
735
736 #ifdef TIOCGETP
737 /*
738  * These are deprecated, but there is limited support..
739  *
740  * The "sg_flags" translation is a joke..
741  */
742 static int get_sgflags(struct tty_struct *tty)
743 {
744         int flags = 0;
745
746         if (!(tty->termios.c_lflag & ICANON)) {
747                 if (tty->termios.c_lflag & ISIG)
748                         flags |= 0x02;          /* cbreak */
749                 else
750                         flags |= 0x20;          /* raw */
751         }
752         if (tty->termios.c_lflag & ECHO)
753                 flags |= 0x08;                  /* echo */
754         if (tty->termios.c_oflag & OPOST)
755                 if (tty->termios.c_oflag & ONLCR)
756                         flags |= 0x10;          /* crmod */
757         return flags;
758 }
759
760 static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
761 {
762         struct sgttyb tmp;
763
764         down_read(&tty->termios_rwsem);
765         tmp.sg_ispeed = tty->termios.c_ispeed;
766         tmp.sg_ospeed = tty->termios.c_ospeed;
767         tmp.sg_erase = tty->termios.c_cc[VERASE];
768         tmp.sg_kill = tty->termios.c_cc[VKILL];
769         tmp.sg_flags = get_sgflags(tty);
770         up_read(&tty->termios_rwsem);
771
772         return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
773 }
774
775 static void set_sgflags(struct ktermios *termios, int flags)
776 {
777         termios->c_iflag = ICRNL | IXON;
778         termios->c_oflag = 0;
779         termios->c_lflag = ISIG | ICANON;
780         if (flags & 0x02) {     /* cbreak */
781                 termios->c_iflag = 0;
782                 termios->c_lflag &= ~ICANON;
783         }
784         if (flags & 0x08) {             /* echo */
785                 termios->c_lflag |= ECHO | ECHOE | ECHOK |
786                                     ECHOCTL | ECHOKE | IEXTEN;
787         }
788         if (flags & 0x10) {             /* crmod */
789                 termios->c_oflag |= OPOST | ONLCR;
790         }
791         if (flags & 0x20) {     /* raw */
792                 termios->c_iflag = 0;
793                 termios->c_lflag &= ~(ISIG | ICANON);
794         }
795         if (!(termios->c_lflag & ICANON)) {
796                 termios->c_cc[VMIN] = 1;
797                 termios->c_cc[VTIME] = 0;
798         }
799 }
800
801 /**
802  *      set_sgttyb              -       set legacy terminal values
803  *      @tty: tty structure
804  *      @sgttyb: pointer to old style terminal structure
805  *
806  *      Updates a terminal from the legacy BSD style terminal information
807  *      structure.
808  *
809  *      Locking: termios_rwsem
810  */
811
812 static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
813 {
814         int retval;
815         struct sgttyb tmp;
816         struct ktermios termios;
817
818         retval = tty_check_change(tty);
819         if (retval)
820                 return retval;
821
822         if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
823                 return -EFAULT;
824
825         down_write(&tty->termios_rwsem);
826         termios = tty->termios;
827         termios.c_cc[VERASE] = tmp.sg_erase;
828         termios.c_cc[VKILL] = tmp.sg_kill;
829         set_sgflags(&termios, tmp.sg_flags);
830         /* Try and encode into Bfoo format */
831 #ifdef BOTHER
832         tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
833                                                 termios.c_ospeed);
834 #endif
835         up_write(&tty->termios_rwsem);
836         tty_set_termios(tty, &termios);
837         return 0;
838 }
839 #endif
840
841 #ifdef TIOCGETC
842 static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
843 {
844         struct tchars tmp;
845
846         down_read(&tty->termios_rwsem);
847         tmp.t_intrc = tty->termios.c_cc[VINTR];
848         tmp.t_quitc = tty->termios.c_cc[VQUIT];
849         tmp.t_startc = tty->termios.c_cc[VSTART];
850         tmp.t_stopc = tty->termios.c_cc[VSTOP];
851         tmp.t_eofc = tty->termios.c_cc[VEOF];
852         tmp.t_brkc = tty->termios.c_cc[VEOL2];  /* what is brkc anyway? */
853         up_read(&tty->termios_rwsem);
854         return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
855 }
856
857 static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
858 {
859         struct tchars tmp;
860
861         if (copy_from_user(&tmp, tchars, sizeof(tmp)))
862                 return -EFAULT;
863         down_write(&tty->termios_rwsem);
864         tty->termios.c_cc[VINTR] = tmp.t_intrc;
865         tty->termios.c_cc[VQUIT] = tmp.t_quitc;
866         tty->termios.c_cc[VSTART] = tmp.t_startc;
867         tty->termios.c_cc[VSTOP] = tmp.t_stopc;
868         tty->termios.c_cc[VEOF] = tmp.t_eofc;
869         tty->termios.c_cc[VEOL2] = tmp.t_brkc;  /* what is brkc anyway? */
870         up_write(&tty->termios_rwsem);
871         return 0;
872 }
873 #endif
874
875 #ifdef TIOCGLTC
876 static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
877 {
878         struct ltchars tmp;
879
880         down_read(&tty->termios_rwsem);
881         tmp.t_suspc = tty->termios.c_cc[VSUSP];
882         /* what is dsuspc anyway? */
883         tmp.t_dsuspc = tty->termios.c_cc[VSUSP];
884         tmp.t_rprntc = tty->termios.c_cc[VREPRINT];
885         /* what is flushc anyway? */
886         tmp.t_flushc = tty->termios.c_cc[VEOL2];
887         tmp.t_werasc = tty->termios.c_cc[VWERASE];
888         tmp.t_lnextc = tty->termios.c_cc[VLNEXT];
889         up_read(&tty->termios_rwsem);
890         return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
891 }
892
893 static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
894 {
895         struct ltchars tmp;
896
897         if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
898                 return -EFAULT;
899
900         down_write(&tty->termios_rwsem);
901         tty->termios.c_cc[VSUSP] = tmp.t_suspc;
902         /* what is dsuspc anyway? */
903         tty->termios.c_cc[VEOL2] = tmp.t_dsuspc;
904         tty->termios.c_cc[VREPRINT] = tmp.t_rprntc;
905         /* what is flushc anyway? */
906         tty->termios.c_cc[VEOL2] = tmp.t_flushc;
907         tty->termios.c_cc[VWERASE] = tmp.t_werasc;
908         tty->termios.c_cc[VLNEXT] = tmp.t_lnextc;
909         up_write(&tty->termios_rwsem);
910         return 0;
911 }
912 #endif
913
914 /**
915  *      tty_change_softcar      -       carrier change ioctl helper
916  *      @tty: tty to update
917  *      @arg: enable/disable CLOCAL
918  *
919  *      Perform a change to the CLOCAL state and call into the driver
920  *      layer to make it visible. All done with the termios rwsem
921  */
922
923 static int tty_change_softcar(struct tty_struct *tty, int arg)
924 {
925         int ret = 0;
926         int bit = arg ? CLOCAL : 0;
927         struct ktermios old;
928
929         down_write(&tty->termios_rwsem);
930         old = tty->termios;
931         tty->termios.c_cflag &= ~CLOCAL;
932         tty->termios.c_cflag |= bit;
933         if (tty->ops->set_termios)
934                 tty->ops->set_termios(tty, &old);
935         if ((tty->termios.c_cflag & CLOCAL) != bit)
936                 ret = -EINVAL;
937         up_write(&tty->termios_rwsem);
938         return ret;
939 }
940
941 /**
942  *      tty_mode_ioctl          -       mode related ioctls
943  *      @tty: tty for the ioctl
944  *      @file: file pointer for the tty
945  *      @cmd: command
946  *      @arg: ioctl argument
947  *
948  *      Perform non line discipline specific mode control ioctls. This
949  *      is designed to be called by line disciplines to ensure they provide
950  *      consistent mode setting.
951  */
952
953 int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
954                         unsigned int cmd, unsigned long arg)
955 {
956         struct tty_struct *real_tty;
957         void __user *p = (void __user *)arg;
958         int ret = 0;
959         struct ktermios kterm;
960
961         BUG_ON(file == NULL);
962
963         if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
964             tty->driver->subtype == PTY_TYPE_MASTER)
965                 real_tty = tty->link;
966         else
967                 real_tty = tty;
968
969         switch (cmd) {
970 #ifdef TIOCGETP
971         case TIOCGETP:
972                 return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
973         case TIOCSETP:
974         case TIOCSETN:
975                 return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
976 #endif
977 #ifdef TIOCGETC
978         case TIOCGETC:
979                 return get_tchars(real_tty, p);
980         case TIOCSETC:
981                 return set_tchars(real_tty, p);
982 #endif
983 #ifdef TIOCGLTC
984         case TIOCGLTC:
985                 return get_ltchars(real_tty, p);
986         case TIOCSLTC:
987                 return set_ltchars(real_tty, p);
988 #endif
989         case TCSETSF:
990                 return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
991         case TCSETSW:
992                 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
993         case TCSETS:
994                 return set_termios(real_tty, p, TERMIOS_OLD);
995 #ifndef TCGETS2
996         case TCGETS:
997                 copy_termios(real_tty, &kterm);
998                 if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
999                         ret = -EFAULT;
1000                 return ret;
1001 #else
1002         case TCGETS:
1003                 copy_termios(real_tty, &kterm);
1004                 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
1005                         ret = -EFAULT;
1006                 return ret;
1007         case TCGETS2:
1008                 copy_termios(real_tty, &kterm);
1009                 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm))
1010                         ret = -EFAULT;
1011                 return ret;
1012         case TCSETSF2:
1013                 return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT);
1014         case TCSETSW2:
1015                 return set_termios(real_tty, p, TERMIOS_WAIT);
1016         case TCSETS2:
1017                 return set_termios(real_tty, p, 0);
1018 #endif
1019         case TCGETA:
1020                 return get_termio(real_tty, p);
1021         case TCSETAF:
1022                 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
1023         case TCSETAW:
1024                 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
1025         case TCSETA:
1026                 return set_termios(real_tty, p, TERMIOS_TERMIO);
1027 #ifndef TCGETS2
1028         case TIOCGLCKTRMIOS:
1029                 copy_termios_locked(real_tty, &kterm);
1030                 if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
1031                         ret = -EFAULT;
1032                 return ret;
1033         case TIOCSLCKTRMIOS:
1034                 if (!capable(CAP_SYS_ADMIN))
1035                         return -EPERM;
1036                 copy_termios_locked(real_tty, &kterm);
1037                 if (user_termios_to_kernel_termios(&kterm,
1038                                                (struct termios __user *) arg))
1039                         return -EFAULT;
1040                 down_write(&real_tty->termios_rwsem);
1041                 real_tty->termios_locked = kterm;
1042                 up_write(&real_tty->termios_rwsem);
1043                 return 0;
1044 #else
1045         case TIOCGLCKTRMIOS:
1046                 copy_termios_locked(real_tty, &kterm);
1047                 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
1048                         ret = -EFAULT;
1049                 return ret;
1050         case TIOCSLCKTRMIOS:
1051                 if (!capable(CAP_SYS_ADMIN))
1052                         return -EPERM;
1053                 copy_termios_locked(real_tty, &kterm);
1054                 if (user_termios_to_kernel_termios_1(&kterm,
1055                                                (struct termios __user *) arg))
1056                         return -EFAULT;
1057                 down_write(&real_tty->termios_rwsem);
1058                 real_tty->termios_locked = kterm;
1059                 up_write(&real_tty->termios_rwsem);
1060                 return ret;
1061 #endif
1062 #ifdef TCGETX
1063         case TCGETX: {
1064                 struct termiox ktermx;
1065                 if (real_tty->termiox == NULL)
1066                         return -EINVAL;
1067                 down_read(&real_tty->termios_rwsem);
1068                 memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox));
1069                 up_read(&real_tty->termios_rwsem);
1070                 if (copy_to_user(p, &ktermx, sizeof(struct termiox)))
1071                         ret = -EFAULT;
1072                 return ret;
1073         }
1074         case TCSETX:
1075                 return set_termiox(real_tty, p, 0);
1076         case TCSETXW:
1077                 return set_termiox(real_tty, p, TERMIOS_WAIT);
1078         case TCSETXF:
1079                 return set_termiox(real_tty, p, TERMIOS_FLUSH);
1080 #endif          
1081         case TIOCGSOFTCAR:
1082                 copy_termios(real_tty, &kterm);
1083                 ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0,
1084                                                 (int __user *)arg);
1085                 return ret;
1086         case TIOCSSOFTCAR:
1087                 if (get_user(arg, (unsigned int __user *) arg))
1088                         return -EFAULT;
1089                 return tty_change_softcar(real_tty, arg);
1090         default:
1091                 return -ENOIOCTLCMD;
1092         }
1093 }
1094 EXPORT_SYMBOL_GPL(tty_mode_ioctl);
1095
1096
1097 /* Caller guarantees ldisc reference is held */
1098 static int __tty_perform_flush(struct tty_struct *tty, unsigned long arg)
1099 {
1100         struct tty_ldisc *ld = tty->ldisc;
1101
1102         switch (arg) {
1103         case TCIFLUSH:
1104                 if (ld && ld->ops->flush_buffer) {
1105                         ld->ops->flush_buffer(tty);
1106                         tty_unthrottle(tty);
1107                 }
1108                 break;
1109         case TCIOFLUSH:
1110                 if (ld && ld->ops->flush_buffer) {
1111                         ld->ops->flush_buffer(tty);
1112                         tty_unthrottle(tty);
1113                 }
1114                 /* fall through */
1115         case TCOFLUSH:
1116                 tty_driver_flush_buffer(tty);
1117                 break;
1118         default:
1119                 return -EINVAL;
1120         }
1121         return 0;
1122 }
1123
1124 int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
1125 {
1126         struct tty_ldisc *ld;
1127         int retval = tty_check_change(tty);
1128         if (retval)
1129                 return retval;
1130
1131         ld = tty_ldisc_ref_wait(tty);
1132         retval = __tty_perform_flush(tty, arg);
1133         if (ld)
1134                 tty_ldisc_deref(ld);
1135         return retval;
1136 }
1137 EXPORT_SYMBOL_GPL(tty_perform_flush);
1138
1139 int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
1140                        unsigned int cmd, unsigned long arg)
1141 {
1142         int retval;
1143
1144         switch (cmd) {
1145         case TCXONC:
1146                 retval = tty_check_change(tty);
1147                 if (retval)
1148                         return retval;
1149                 switch (arg) {
1150                 case TCOOFF:
1151                         spin_lock_irq(&tty->flow_lock);
1152                         if (!tty->flow_stopped) {
1153                                 tty->flow_stopped = 1;
1154                                 __stop_tty(tty);
1155                         }
1156                         spin_unlock_irq(&tty->flow_lock);
1157                         break;
1158                 case TCOON:
1159                         spin_lock_irq(&tty->flow_lock);
1160                         if (tty->flow_stopped) {
1161                                 tty->flow_stopped = 0;
1162                                 __start_tty(tty);
1163                         }
1164                         spin_unlock_irq(&tty->flow_lock);
1165                         break;
1166                 case TCIOFF:
1167                         down_read(&tty->termios_rwsem);
1168                         if (STOP_CHAR(tty) != __DISABLED_CHAR)
1169                                 retval = tty_send_xchar(tty, STOP_CHAR(tty));
1170                         up_read(&tty->termios_rwsem);
1171                         break;
1172                 case TCION:
1173                         down_read(&tty->termios_rwsem);
1174                         if (START_CHAR(tty) != __DISABLED_CHAR)
1175                                 retval = tty_send_xchar(tty, START_CHAR(tty));
1176                         up_read(&tty->termios_rwsem);
1177                         break;
1178                 default:
1179                         return -EINVAL;
1180                 }
1181                 return retval;
1182         case TCFLSH:
1183                 retval = tty_check_change(tty);
1184                 if (retval)
1185                         return retval;
1186                 return __tty_perform_flush(tty, arg);
1187         default:
1188                 /* Try the mode commands */
1189                 return tty_mode_ioctl(tty, file, cmd, arg);
1190         }
1191 }
1192 EXPORT_SYMBOL(n_tty_ioctl_helper);
1193
1194 #ifdef CONFIG_COMPAT
1195 long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file,
1196                                         unsigned int cmd, unsigned long arg)
1197 {
1198         switch (cmd) {
1199         case TIOCGLCKTRMIOS:
1200         case TIOCSLCKTRMIOS:
1201                 return tty_mode_ioctl(tty, file, cmd, (unsigned long) compat_ptr(arg));
1202         default:
1203                 return -ENOIOCTLCMD;
1204         }
1205 }
1206 EXPORT_SYMBOL(n_tty_compat_ioctl_helper);
1207 #endif
1208