]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/char/tty_ioctl.c
tty: Add termiox
[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 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
583 #ifdef TCGETX
584
585 /**
586  *      set_termiox     -       set termiox fields if possible
587  *      @tty: terminal
588  *      @arg: termiox structure from user
589  *      @opt: option flags for ioctl type
590  *
591  *      Implement the device calling points for the SYS5 termiox ioctl
592  *      interface in Linux
593  */
594
595 static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
596 {
597         struct termiox tnew;
598         struct tty_ldisc *ld;
599
600         if (tty->termiox == NULL)
601                 return -EINVAL;
602         if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
603                 return -EFAULT;
604
605         ld = tty_ldisc_ref(tty);
606         if (ld != NULL) {
607                 if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
608                         ld->ops->flush_buffer(tty);
609                 tty_ldisc_deref(ld);
610         }
611         if (opt & TERMIOS_WAIT) {
612                 tty_wait_until_sent(tty, 0);
613                 if (signal_pending(current))
614                         return -EINTR;
615         }
616
617         mutex_lock(&tty->termios_mutex);
618         if (tty->ops->set_termiox)
619                 tty->ops->set_termiox(tty, &tnew);
620         mutex_unlock(&tty->termios_mutex);
621         return 0;
622 }
623
624 #endif
625
626 static unsigned long inq_canon(struct tty_struct *tty)
627 {
628         int nr, head, tail;
629
630         if (!tty->canon_data || !tty->read_buf)
631                 return 0;
632         head = tty->canon_head;
633         tail = tty->read_tail;
634         nr = (head - tail) & (N_TTY_BUF_SIZE-1);
635         /* Skip EOF-chars.. */
636         while (head != tail) {
637                 if (test_bit(tail, tty->read_flags) &&
638                     tty->read_buf[tail] == __DISABLED_CHAR)
639                         nr--;
640                 tail = (tail+1) & (N_TTY_BUF_SIZE-1);
641         }
642         return nr;
643 }
644
645 #ifdef TIOCGETP
646 /*
647  * These are deprecated, but there is limited support..
648  *
649  * The "sg_flags" translation is a joke..
650  */
651 static int get_sgflags(struct tty_struct *tty)
652 {
653         int flags = 0;
654
655         if (!(tty->termios->c_lflag & ICANON)) {
656                 if (tty->termios->c_lflag & ISIG)
657                         flags |= 0x02;          /* cbreak */
658                 else
659                         flags |= 0x20;          /* raw */
660         }
661         if (tty->termios->c_lflag & ECHO)
662                 flags |= 0x08;                  /* echo */
663         if (tty->termios->c_oflag & OPOST)
664                 if (tty->termios->c_oflag & ONLCR)
665                         flags |= 0x10;          /* crmod */
666         return flags;
667 }
668
669 static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
670 {
671         struct sgttyb tmp;
672
673         mutex_lock(&tty->termios_mutex);
674         tmp.sg_ispeed = tty->termios->c_ispeed;
675         tmp.sg_ospeed = tty->termios->c_ospeed;
676         tmp.sg_erase = tty->termios->c_cc[VERASE];
677         tmp.sg_kill = tty->termios->c_cc[VKILL];
678         tmp.sg_flags = get_sgflags(tty);
679         mutex_unlock(&tty->termios_mutex);
680
681         return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
682 }
683
684 static void set_sgflags(struct ktermios *termios, int flags)
685 {
686         termios->c_iflag = ICRNL | IXON;
687         termios->c_oflag = 0;
688         termios->c_lflag = ISIG | ICANON;
689         if (flags & 0x02) {     /* cbreak */
690                 termios->c_iflag = 0;
691                 termios->c_lflag &= ~ICANON;
692         }
693         if (flags & 0x08) {             /* echo */
694                 termios->c_lflag |= ECHO | ECHOE | ECHOK |
695                                     ECHOCTL | ECHOKE | IEXTEN;
696         }
697         if (flags & 0x10) {             /* crmod */
698                 termios->c_oflag |= OPOST | ONLCR;
699         }
700         if (flags & 0x20) {     /* raw */
701                 termios->c_iflag = 0;
702                 termios->c_lflag &= ~(ISIG | ICANON);
703         }
704         if (!(termios->c_lflag & ICANON)) {
705                 termios->c_cc[VMIN] = 1;
706                 termios->c_cc[VTIME] = 0;
707         }
708 }
709
710 /**
711  *      set_sgttyb              -       set legacy terminal values
712  *      @tty: tty structure
713  *      @sgttyb: pointer to old style terminal structure
714  *
715  *      Updates a terminal from the legacy BSD style terminal information
716  *      structure.
717  *
718  *      Locking: termios_sem
719  */
720
721 static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
722 {
723         int retval;
724         struct sgttyb tmp;
725         struct ktermios termios;
726
727         retval = tty_check_change(tty);
728         if (retval)
729                 return retval;
730
731         if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
732                 return -EFAULT;
733
734         mutex_lock(&tty->termios_mutex);
735         termios = *tty->termios;
736         termios.c_cc[VERASE] = tmp.sg_erase;
737         termios.c_cc[VKILL] = tmp.sg_kill;
738         set_sgflags(&termios, tmp.sg_flags);
739         /* Try and encode into Bfoo format */
740 #ifdef BOTHER
741         tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
742                                                 termios.c_ospeed);
743 #endif
744         mutex_unlock(&tty->termios_mutex);
745         change_termios(tty, &termios);
746         return 0;
747 }
748 #endif
749
750 #ifdef TIOCGETC
751 static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
752 {
753         struct tchars tmp;
754
755         mutex_lock(&tty->termios_mutex);
756         tmp.t_intrc = tty->termios->c_cc[VINTR];
757         tmp.t_quitc = tty->termios->c_cc[VQUIT];
758         tmp.t_startc = tty->termios->c_cc[VSTART];
759         tmp.t_stopc = tty->termios->c_cc[VSTOP];
760         tmp.t_eofc = tty->termios->c_cc[VEOF];
761         tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
762         mutex_unlock(&tty->termios_mutex);
763         return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
764 }
765
766 static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
767 {
768         struct tchars tmp;
769
770         if (copy_from_user(&tmp, tchars, sizeof(tmp)))
771                 return -EFAULT;
772         mutex_lock(&tty->termios_mutex);
773         tty->termios->c_cc[VINTR] = tmp.t_intrc;
774         tty->termios->c_cc[VQUIT] = tmp.t_quitc;
775         tty->termios->c_cc[VSTART] = tmp.t_startc;
776         tty->termios->c_cc[VSTOP] = tmp.t_stopc;
777         tty->termios->c_cc[VEOF] = tmp.t_eofc;
778         tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
779         mutex_unlock(&tty->termios_mutex);
780         return 0;
781 }
782 #endif
783
784 #ifdef TIOCGLTC
785 static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
786 {
787         struct ltchars tmp;
788
789         mutex_lock(&tty->termios_mutex);
790         tmp.t_suspc = tty->termios->c_cc[VSUSP];
791         /* what is dsuspc anyway? */
792         tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
793         tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
794         /* what is flushc anyway? */
795         tmp.t_flushc = tty->termios->c_cc[VEOL2];
796         tmp.t_werasc = tty->termios->c_cc[VWERASE];
797         tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
798         mutex_unlock(&tty->termios_mutex);
799         return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
800 }
801
802 static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
803 {
804         struct ltchars tmp;
805
806         if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
807                 return -EFAULT;
808
809         mutex_lock(&tty->termios_mutex);
810         tty->termios->c_cc[VSUSP] = tmp.t_suspc;
811         /* what is dsuspc anyway? */
812         tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
813         tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
814         /* what is flushc anyway? */
815         tty->termios->c_cc[VEOL2] = tmp.t_flushc;
816         tty->termios->c_cc[VWERASE] = tmp.t_werasc;
817         tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
818         mutex_unlock(&tty->termios_mutex);
819         return 0;
820 }
821 #endif
822
823 /**
824  *      send_prio_char          -       send priority character
825  *
826  *      Send a high priority character to the tty even if stopped
827  *
828  *      Locking: none for xchar method, write ordering for write method.
829  */
830
831 static int send_prio_char(struct tty_struct *tty, char ch)
832 {
833         int     was_stopped = tty->stopped;
834
835         if (tty->ops->send_xchar) {
836                 tty->ops->send_xchar(tty, ch);
837                 return 0;
838         }
839
840         if (tty_write_lock(tty, 0) < 0)
841                 return -ERESTARTSYS;
842
843         if (was_stopped)
844                 start_tty(tty);
845         tty->ops->write(tty, &ch, 1);
846         if (was_stopped)
847                 stop_tty(tty);
848         tty_write_unlock(tty);
849         return 0;
850 }
851
852 /**
853  *      tty_change_softcar      -       carrier change ioctl helper
854  *      @tty: tty to update
855  *      @arg: enable/disable CLOCAL
856  *
857  *      Perform a change to the CLOCAL state and call into the driver
858  *      layer to make it visible. All done with the termios mutex
859  */
860
861 static int tty_change_softcar(struct tty_struct *tty, int arg)
862 {
863         int ret = 0;
864         int bit = arg ? CLOCAL : 0;
865         struct ktermios old;
866
867         mutex_lock(&tty->termios_mutex);
868         old = *tty->termios;
869         tty->termios->c_cflag &= ~CLOCAL;
870         tty->termios->c_cflag |= bit;
871         if (tty->ops->set_termios)
872                 tty->ops->set_termios(tty, &old);
873         if ((tty->termios->c_cflag & CLOCAL) != bit)
874                 ret = -EINVAL;
875         mutex_unlock(&tty->termios_mutex);
876         return ret;
877 }
878
879 /**
880  *      tty_mode_ioctl          -       mode related ioctls
881  *      @tty: tty for the ioctl
882  *      @file: file pointer for the tty
883  *      @cmd: command
884  *      @arg: ioctl argument
885  *
886  *      Perform non line discipline specific mode control ioctls. This
887  *      is designed to be called by line disciplines to ensure they provide
888  *      consistent mode setting.
889  */
890
891 int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
892                         unsigned int cmd, unsigned long arg)
893 {
894         struct tty_struct *real_tty;
895         void __user *p = (void __user *)arg;
896
897         if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
898             tty->driver->subtype == PTY_TYPE_MASTER)
899                 real_tty = tty->link;
900         else
901                 real_tty = tty;
902
903         switch (cmd) {
904 #ifdef TIOCGETP
905         case TIOCGETP:
906                 return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
907         case TIOCSETP:
908         case TIOCSETN:
909                 return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
910 #endif
911 #ifdef TIOCGETC
912         case TIOCGETC:
913                 return get_tchars(real_tty, p);
914         case TIOCSETC:
915                 return set_tchars(real_tty, p);
916 #endif
917 #ifdef TIOCGLTC
918         case TIOCGLTC:
919                 return get_ltchars(real_tty, p);
920         case TIOCSLTC:
921                 return set_ltchars(real_tty, p);
922 #endif
923         case TCSETSF:
924                 return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
925         case TCSETSW:
926                 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
927         case TCSETS:
928                 return set_termios(real_tty, p, TERMIOS_OLD);
929 #ifndef TCGETS2
930         case TCGETS:
931                 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
932                         return -EFAULT;
933                 return 0;
934 #else
935         case TCGETS:
936                 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios))
937                         return -EFAULT;
938                 return 0;
939         case TCGETS2:
940                 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios))
941                         return -EFAULT;
942                 return 0;
943         case TCSETSF2:
944                 return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT);
945         case TCSETSW2:
946                 return set_termios(real_tty, p, TERMIOS_WAIT);
947         case TCSETS2:
948                 return set_termios(real_tty, p, 0);
949 #endif
950         case TCGETA:
951                 return get_termio(real_tty, p);
952         case TCSETAF:
953                 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
954         case TCSETAW:
955                 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
956         case TCSETA:
957                 return set_termios(real_tty, p, TERMIOS_TERMIO);
958 #ifndef TCGETS2
959         case TIOCGLCKTRMIOS:
960                 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
961                         return -EFAULT;
962                 return 0;
963         case TIOCSLCKTRMIOS:
964                 if (!capable(CAP_SYS_ADMIN))
965                         return -EPERM;
966                 if (user_termios_to_kernel_termios(real_tty->termios_locked,
967                                                (struct termios __user *) arg))
968                         return -EFAULT;
969                 return 0;
970 #else
971         case TIOCGLCKTRMIOS:
972                 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
973                         return -EFAULT;
974                 return 0;
975         case TIOCSLCKTRMIOS:
976                 if (!capable(CAP_SYS_ADMIN))
977                         return -EPERM;
978                 if (user_termios_to_kernel_termios_1(real_tty->termios_locked,
979                                                (struct termios __user *) arg))
980                         return -EFAULT;
981                         return 0;
982 #endif
983 #ifdef TCGETX
984         case TCGETX:
985                 if (real_tty->termiox == NULL)
986                         return -EINVAL;
987                 if (copy_to_user(p, real_tty->termiox, sizeof(struct termiox)))
988                         return -EFAULT;
989                 return 0;
990         case TCSETX:
991                 return set_termiox(real_tty, p, 0);
992         case TCSETXW:
993                 return set_termiox(real_tty, p, TERMIOS_WAIT);
994         case TCSETXF:
995                 return set_termiox(real_tty, p, TERMIOS_FLUSH);
996 #endif          
997         case TIOCGSOFTCAR:
998                 /* FIXME: for correctness we may need to take the termios
999                    lock here - review */
1000                 return put_user(C_CLOCAL(real_tty) ? 1 : 0,
1001                                                 (int __user *)arg);
1002         case TIOCSSOFTCAR:
1003                 if (get_user(arg, (unsigned int __user *) arg))
1004                         return -EFAULT;
1005                 return tty_change_softcar(real_tty, arg);
1006         default:
1007                 return -ENOIOCTLCMD;
1008         }
1009 }
1010 EXPORT_SYMBOL_GPL(tty_mode_ioctl);
1011
1012 int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
1013 {
1014         struct tty_ldisc *ld;
1015         int retval = tty_check_change(tty);
1016         if (retval)
1017                 return retval;
1018
1019         ld = tty_ldisc_ref(tty);
1020         switch (arg) {
1021         case TCIFLUSH:
1022                 if (ld && ld->ops->flush_buffer)
1023                         ld->ops->flush_buffer(tty);
1024                 break;
1025         case TCIOFLUSH:
1026                 if (ld && ld->ops->flush_buffer)
1027                         ld->ops->flush_buffer(tty);
1028                 /* fall through */
1029         case TCOFLUSH:
1030                 tty_driver_flush_buffer(tty);
1031                 break;
1032         default:
1033                 tty_ldisc_deref(ld);
1034                 return -EINVAL;
1035         }
1036         tty_ldisc_deref(ld);
1037         return 0;
1038 }
1039 EXPORT_SYMBOL_GPL(tty_perform_flush);
1040
1041 int n_tty_ioctl(struct tty_struct *tty, struct file *file,
1042                        unsigned int cmd, unsigned long arg)
1043 {
1044         unsigned long flags;
1045         int retval;
1046
1047         switch (cmd) {
1048         case TCXONC:
1049                 retval = tty_check_change(tty);
1050                 if (retval)
1051                         return retval;
1052                 switch (arg) {
1053                 case TCOOFF:
1054                         if (!tty->flow_stopped) {
1055                                 tty->flow_stopped = 1;
1056                                 stop_tty(tty);
1057                         }
1058                         break;
1059                 case TCOON:
1060                         if (tty->flow_stopped) {
1061                                 tty->flow_stopped = 0;
1062                                 start_tty(tty);
1063                         }
1064                         break;
1065                 case TCIOFF:
1066                         if (STOP_CHAR(tty) != __DISABLED_CHAR)
1067                                 return send_prio_char(tty, STOP_CHAR(tty));
1068                         break;
1069                 case TCION:
1070                         if (START_CHAR(tty) != __DISABLED_CHAR)
1071                                 return send_prio_char(tty, START_CHAR(tty));
1072                         break;
1073                 default:
1074                         return -EINVAL;
1075                 }
1076                 return 0;
1077         case TCFLSH:
1078                 return tty_perform_flush(tty, arg);
1079         case TIOCOUTQ:
1080                 return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
1081         case TIOCINQ:
1082                 retval = tty->read_cnt;
1083                 if (L_ICANON(tty))
1084                         retval = inq_canon(tty);
1085                 return put_user(retval, (unsigned int __user *) arg);
1086         case TIOCPKT:
1087         {
1088                 int pktmode;
1089
1090                 if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
1091                     tty->driver->subtype != PTY_TYPE_MASTER)
1092                         return -ENOTTY;
1093                 if (get_user(pktmode, (int __user *) arg))
1094                         return -EFAULT;
1095                 spin_lock_irqsave(&tty->ctrl_lock, flags);
1096                 if (pktmode) {
1097                         if (!tty->packet) {
1098                                 tty->packet = 1;
1099                                 tty->link->ctrl_status = 0;
1100                         }
1101                 } else
1102                         tty->packet = 0;
1103                 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1104                 return 0;
1105         }
1106         default:
1107                 /* Try the mode commands */
1108                 return tty_mode_ioctl(tty, file, cmd, arg);
1109         }
1110 }
1111 EXPORT_SYMBOL(n_tty_ioctl);