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