]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/char/tty_ioctl.c
30670851e51aa0a7d2fc058f9187b78efe2d9827
[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         int ret = 0;
897
898         if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
899             tty->driver->subtype == PTY_TYPE_MASTER)
900                 real_tty = tty->link;
901         else
902                 real_tty = tty;
903
904         switch (cmd) {
905 #ifdef TIOCGETP
906         case TIOCGETP:
907                 return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
908         case TIOCSETP:
909         case TIOCSETN:
910                 return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
911 #endif
912 #ifdef TIOCGETC
913         case TIOCGETC:
914                 return get_tchars(real_tty, p);
915         case TIOCSETC:
916                 return set_tchars(real_tty, p);
917 #endif
918 #ifdef TIOCGLTC
919         case TIOCGLTC:
920                 return get_ltchars(real_tty, p);
921         case TIOCSLTC:
922                 return set_ltchars(real_tty, p);
923 #endif
924         case TCSETSF:
925                 return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
926         case TCSETSW:
927                 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
928         case TCSETS:
929                 return set_termios(real_tty, p, TERMIOS_OLD);
930 #ifndef TCGETS2
931         case TCGETS:
932                 mutex_lock(&real_tty->termios_mutex);
933                 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
934                         ret = -EFAULT;
935                 mutex_unlock(&real_tty->termios_mutex);
936                 return ret;
937 #else
938         case TCGETS:
939                 mutex_lock(&real_tty->termios_mutex);
940                 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios))
941                         ret = -EFAULT;
942                 mutex_unlock(&real_tty->termios_mutex);
943                 return ret;
944         case TCGETS2:
945                 mutex_lock(&real_tty->termios_mutex);
946                 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios))
947                         ret = -EFAULT;
948                 mutex_unlock(&real_tty->termios_mutex);
949                 return ret;
950         case TCSETSF2:
951                 return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT);
952         case TCSETSW2:
953                 return set_termios(real_tty, p, TERMIOS_WAIT);
954         case TCSETS2:
955                 return set_termios(real_tty, p, 0);
956 #endif
957         case TCGETA:
958                 return get_termio(real_tty, p);
959         case TCSETAF:
960                 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
961         case TCSETAW:
962                 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
963         case TCSETA:
964                 return set_termios(real_tty, p, TERMIOS_TERMIO);
965 #ifndef TCGETS2
966         case TIOCGLCKTRMIOS:
967                 mutex_lock(&real_tty->termios_mutex);
968                 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
969                         ret = -EFAULT;
970                 mutex_unlock(&real_tty->termios_mutex);
971                 return ret;
972         case TIOCSLCKTRMIOS:
973                 if (!capable(CAP_SYS_ADMIN))
974                         return -EPERM;
975                 mutex_lock(&real_tty->termios_mutex);
976                 if (user_termios_to_kernel_termios(real_tty->termios_locked,
977                                                (struct termios __user *) arg))
978                         ret = -EFAULT;
979                 mutex_unlock(&real_tty->termios_mutex);
980                 return ret;
981 #else
982         case TIOCGLCKTRMIOS:
983                 mutex_lock(&real_tty->termios_mutex);
984                 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
985                         ret = -EFAULT;
986                 mutex_unlock(&real_tty->termios_mutex);
987                 return ret;
988         case TIOCSLCKTRMIOS:
989                 if (!capable(CAP_SYS_ADMIN))
990                         ret = -EPERM;
991                 mutex_lock(&real_tty->termios_mutex);
992                 if (user_termios_to_kernel_termios_1(real_tty->termios_locked,
993                                                (struct termios __user *) arg))
994                         ret = -EFAULT;
995                 mutex_unlock(&real_tty->termios_mutex);
996                 return ret;
997 #endif
998 #ifdef TCGETX
999         case TCGETX:
1000                 if (real_tty->termiox == NULL)
1001                         return -EINVAL;
1002                 mutex_lock(&real_tty->termios_mutex);
1003                 if (copy_to_user(p, real_tty->termiox, sizeof(struct termiox)))
1004                         ret = -EFAULT;
1005                 mutex_unlock(&real_tty->termios_mutex);
1006                 return ret;
1007         case TCSETX:
1008                 return set_termiox(real_tty, p, 0);
1009         case TCSETXW:
1010                 return set_termiox(real_tty, p, TERMIOS_WAIT);
1011         case TCSETXF:
1012                 return set_termiox(real_tty, p, TERMIOS_FLUSH);
1013 #endif          
1014         case TIOCGSOFTCAR:
1015                 mutex_lock(&real_tty->termios_mutex);
1016                 ret = put_user(C_CLOCAL(real_tty) ? 1 : 0,
1017                                                 (int __user *)arg);
1018                 mutex_unlock(&real_tty->termios_mutex);
1019                 return ret;
1020         case TIOCSSOFTCAR:
1021                 if (get_user(arg, (unsigned int __user *) arg))
1022                         return -EFAULT;
1023                 return tty_change_softcar(real_tty, arg);
1024         default:
1025                 return -ENOIOCTLCMD;
1026         }
1027 }
1028 EXPORT_SYMBOL_GPL(tty_mode_ioctl);
1029
1030 int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
1031 {
1032         struct tty_ldisc *ld;
1033         int retval = tty_check_change(tty);
1034         if (retval)
1035                 return retval;
1036
1037         ld = tty_ldisc_ref(tty);
1038         switch (arg) {
1039         case TCIFLUSH:
1040                 if (ld && ld->ops->flush_buffer)
1041                         ld->ops->flush_buffer(tty);
1042                 break;
1043         case TCIOFLUSH:
1044                 if (ld && ld->ops->flush_buffer)
1045                         ld->ops->flush_buffer(tty);
1046                 /* fall through */
1047         case TCOFLUSH:
1048                 tty_driver_flush_buffer(tty);
1049                 break;
1050         default:
1051                 tty_ldisc_deref(ld);
1052                 return -EINVAL;
1053         }
1054         tty_ldisc_deref(ld);
1055         return 0;
1056 }
1057 EXPORT_SYMBOL_GPL(tty_perform_flush);
1058
1059 int n_tty_ioctl(struct tty_struct *tty, struct file *file,
1060                        unsigned int cmd, unsigned long arg)
1061 {
1062         unsigned long flags;
1063         int retval;
1064
1065         switch (cmd) {
1066         case TCXONC:
1067                 retval = tty_check_change(tty);
1068                 if (retval)
1069                         return retval;
1070                 switch (arg) {
1071                 case TCOOFF:
1072                         if (!tty->flow_stopped) {
1073                                 tty->flow_stopped = 1;
1074                                 stop_tty(tty);
1075                         }
1076                         break;
1077                 case TCOON:
1078                         if (tty->flow_stopped) {
1079                                 tty->flow_stopped = 0;
1080                                 start_tty(tty);
1081                         }
1082                         break;
1083                 case TCIOFF:
1084                         if (STOP_CHAR(tty) != __DISABLED_CHAR)
1085                                 return send_prio_char(tty, STOP_CHAR(tty));
1086                         break;
1087                 case TCION:
1088                         if (START_CHAR(tty) != __DISABLED_CHAR)
1089                                 return send_prio_char(tty, START_CHAR(tty));
1090                         break;
1091                 default:
1092                         return -EINVAL;
1093                 }
1094                 return 0;
1095         case TCFLSH:
1096                 return tty_perform_flush(tty, arg);
1097         case TIOCOUTQ:
1098                 return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
1099         case TIOCINQ:
1100                 retval = tty->read_cnt;
1101                 if (L_ICANON(tty))
1102                         retval = inq_canon(tty);
1103                 return put_user(retval, (unsigned int __user *) arg);
1104         case TIOCPKT:
1105         {
1106                 int pktmode;
1107
1108                 if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
1109                     tty->driver->subtype != PTY_TYPE_MASTER)
1110                         return -ENOTTY;
1111                 if (get_user(pktmode, (int __user *) arg))
1112                         return -EFAULT;
1113                 spin_lock_irqsave(&tty->ctrl_lock, flags);
1114                 if (pktmode) {
1115                         if (!tty->packet) {
1116                                 tty->packet = 1;
1117                                 tty->link->ctrl_status = 0;
1118                         }
1119                 } else
1120                         tty->packet = 0;
1121                 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1122                 return 0;
1123         }
1124         default:
1125                 /* Try the mode commands */
1126                 return tty_mode_ioctl(tty, file, cmd, arg);
1127         }
1128 }
1129 EXPORT_SYMBOL(n_tty_ioctl);