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