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