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