Merge branch 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[pandora-kernel.git] / drivers / char / tty_ioctl.c
1 /*
2  *  linux/drivers/char/tty_ioctl.c
3  *
4  *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
5  *
6  * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
7  * which can be dynamically activated and de-activated by the line
8  * discipline handling modules (like SLIP).
9  */
10
11 #include <linux/types.h>
12 #include <linux/termios.h>
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/major.h>
17 #include <linux/tty.h>
18 #include <linux/fcntl.h>
19 #include <linux/string.h>
20 #include <linux/mm.h>
21 #include <linux/module.h>
22 #include <linux/bitops.h>
23 #include <linux/mutex.h>
24
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         DECLARE_WAITQUEUE(wait, current);
56
57 #ifdef TTY_DEBUG_WAIT_UNTIL_SENT
58         char buf[64];
59         
60         printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
61 #endif
62         if (!tty->driver->chars_in_buffer)
63                 return;
64         add_wait_queue(&tty->write_wait, &wait);
65         if (!timeout)
66                 timeout = MAX_SCHEDULE_TIMEOUT;
67         do {
68 #ifdef TTY_DEBUG_WAIT_UNTIL_SENT
69                 printk(KERN_DEBUG "waiting %s...(%d)\n", tty_name(tty, buf),
70                        tty->driver->chars_in_buffer(tty));
71 #endif
72                 set_current_state(TASK_INTERRUPTIBLE);
73                 if (signal_pending(current))
74                         goto stop_waiting;
75                 if (!tty->driver->chars_in_buffer(tty))
76                         break;
77                 timeout = schedule_timeout(timeout);
78         } while (timeout);
79         if (tty->driver->wait_until_sent)
80                 tty->driver->wait_until_sent(tty, timeout);
81 stop_waiting:
82         set_current_state(TASK_RUNNING);
83         remove_wait_queue(&tty->write_wait, &wait);
84 }
85
86 EXPORT_SYMBOL(tty_wait_until_sent);
87
88 static void unset_locked_termios(struct ktermios *termios,
89                                  struct ktermios *old,
90                                  struct ktermios *locked)
91 {
92         int     i;
93         
94 #define NOSET_MASK(x,y,z) (x = ((x) & ~(z)) | ((y) & (z)))
95
96         if (!locked) {
97                 printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
98                 return;
99         }
100
101         NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
102         NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
103         NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
104         NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
105         termios->c_line = locked->c_line ? old->c_line : termios->c_line;
106         for (i=0; i < NCCS; i++)
107                 termios->c_cc[i] = locked->c_cc[i] ?
108                         old->c_cc[i] : termios->c_cc[i];
109         /* FIXME: What should we do for i/ospeed */
110 }
111
112 /*
113  * Routine which returns the baud rate of the tty
114  *
115  * Note that the baud_table needs to be kept in sync with the
116  * include/asm/termbits.h file.
117  */
118 static const speed_t baud_table[] = {
119         0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
120         9600, 19200, 38400, 57600, 115200, 230400, 460800,
121 #ifdef __sparc__
122         76800, 153600, 307200, 614400, 921600
123 #else
124         500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
125         2500000, 3000000, 3500000, 4000000
126 #endif
127 };
128
129 #ifndef __sparc__
130 static const tcflag_t baud_bits[] = {
131         B0, B50, B75, B110, B134, B150, B200, B300, B600,
132         B1200, B1800, B2400, B4800, B9600, B19200, B38400,
133         B57600, B115200, B230400, B460800, B500000, B576000,
134         B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
135         B3000000, B3500000, B4000000
136 };
137 #else
138 static const tcflag_t baud_bits[] = {
139         B0, B50, B75, B110, B134, B150, B200, B300, B600,
140         B1200, B1800, B2400, B4800, B9600, B19200, B38400,
141         B57600, B115200, B230400, B460800, B76800, B153600,
142         B307200, B614400, B921600
143 };
144 #endif
145
146 static int n_baud_table = ARRAY_SIZE(baud_table);
147
148 /**
149  *      tty_termios_baud_rate
150  *      @termios: termios structure
151  *
152  *      Convert termios baud rate data into a speed. This should be called
153  *      with the termios lock held if this termios is a terminal termios
154  *      structure. May change the termios data. Device drivers can call this
155  *      function but should use ->c_[io]speed directly as they are updated.
156  *
157  *      Locking: none
158  */
159
160 speed_t tty_termios_baud_rate(struct ktermios *termios)
161 {
162         unsigned int cbaud;
163
164         cbaud = termios->c_cflag & CBAUD;
165
166 #ifdef BOTHER
167         /* Magic token for arbitary speed via c_ispeed/c_ospeed */
168         if (cbaud == BOTHER)
169                 return termios->c_ospeed;
170 #endif
171         if (cbaud & CBAUDEX) {
172                 cbaud &= ~CBAUDEX;
173
174                 if (cbaud < 1 || cbaud + 15 > n_baud_table)
175                         termios->c_cflag &= ~CBAUDEX;
176                 else
177                         cbaud += 15;
178         }
179         return baud_table[cbaud];
180 }
181
182 EXPORT_SYMBOL(tty_termios_baud_rate);
183
184 /**
185  *      tty_termios_input_baud_rate
186  *      @termios: termios structure
187  *
188  *      Convert termios baud rate data into a speed. This should be called
189  *      with the termios lock held if this termios is a terminal termios
190  *      structure. May change the termios data. Device drivers can call this
191  *      function but should use ->c_[io]speed directly as they are updated.
192  *
193  *      Locking: none
194  */
195
196 speed_t tty_termios_input_baud_rate(struct ktermios *termios)
197 {
198 #ifdef IBSHIFT
199         unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
200
201         if (cbaud == B0)
202                 return tty_termios_baud_rate(termios);
203
204         /* Magic token for arbitary speed via c_ispeed*/
205         if (cbaud == BOTHER)
206                 return termios->c_ispeed;
207
208         if (cbaud & CBAUDEX) {
209                 cbaud &= ~CBAUDEX;
210
211                 if (cbaud < 1 || cbaud + 15 > n_baud_table)
212                         termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
213                 else
214                         cbaud += 15;
215         }
216         return baud_table[cbaud];
217 #else
218         return tty_termios_baud_rate(termios);
219 #endif
220 }
221
222 EXPORT_SYMBOL(tty_termios_input_baud_rate);
223
224 #ifdef BOTHER
225
226 /**
227  *      tty_termios_encode_baud_rate
228  *      @termios: termios structure
229  *      @ispeed: input speed
230  *      @ospeed: output speed
231  *
232  *      Encode the speeds set into the passed termios structure. This is
233  *      used as a library helper for drivers os that they can report back
234  *      the actual speed selected when it differs from the speed requested
235  *
236  *      For now input and output speed must agree.
237  *
238  *      Locking: Caller should hold termios lock. This is already held
239  *      when calling this function from the driver termios handler.
240  */
241
242 void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud)
243 {
244         int i = 0;
245         int ifound = 0, ofound = 0;
246
247         termios->c_ispeed = ibaud;
248         termios->c_ospeed = obaud;
249
250         termios->c_cflag &= ~CBAUD;
251         /* Identical speed means no input encoding (ie B0 << IBSHIFT)*/
252         if (termios->c_ispeed == termios->c_ospeed)
253                 ifound = 1;
254
255         do {
256                 if (obaud == baud_table[i]) {
257                         termios->c_cflag |= baud_bits[i];
258                         ofound = 1;
259                         /* So that if ibaud == obaud we don't set it */
260                         continue;
261                 }
262                 if (ibaud == baud_table[i]) {
263                         termios->c_cflag |= (baud_bits[i] << IBSHIFT);
264                         ifound = 1;
265                 }
266         }
267         while(++i < n_baud_table);
268         if (!ofound)
269                 termios->c_cflag |= BOTHER;
270         if (!ifound)
271                 termios->c_cflag |= (BOTHER << IBSHIFT);
272 }
273
274 EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
275
276 #endif
277
278 /**
279  *      tty_get_baud_rate       -       get tty bit rates
280  *      @tty: tty to query
281  *
282  *      Returns the baud rate as an integer for this terminal. The
283  *      termios lock must be held by the caller and the terminal bit
284  *      flags may be updated.
285  *
286  *      Locking: none
287  */
288
289 speed_t tty_get_baud_rate(struct tty_struct *tty)
290 {
291         speed_t baud = tty_termios_baud_rate(tty->termios);
292
293         if (baud == 38400 && tty->alt_speed) {
294                 if (!tty->warned) {
295                         printk(KERN_WARNING "Use of setserial/setrocket to "
296                                             "set SPD_* flags is deprecated\n");
297                         tty->warned = 1;
298                 }
299                 baud = tty->alt_speed;
300         }
301
302         return baud;
303 }
304
305 EXPORT_SYMBOL(tty_get_baud_rate);
306
307 /**
308  *      change_termios          -       update termios values
309  *      @tty: tty to update
310  *      @new_termios: desired new value
311  *
312  *      Perform updates to the termios values set on this terminal. There
313  *      is a bit of layering violation here with n_tty in terms of the
314  *      internal knowledge of this function.
315  *
316  *      Locking: termios_sem
317  */
318
319 static void change_termios(struct tty_struct * tty, struct ktermios * new_termios)
320 {
321         int canon_change;
322         struct ktermios old_termios = *tty->termios;
323         struct tty_ldisc *ld;
324         
325         /*
326          *      Perform the actual termios internal changes under lock.
327          */
328          
329
330         /* FIXME: we need to decide on some locking/ordering semantics
331            for the set_termios notification eventually */
332         mutex_lock(&tty->termios_mutex);
333
334         *tty->termios = *new_termios;
335         unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
336         canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
337         if (canon_change) {
338                 memset(&tty->read_flags, 0, sizeof tty->read_flags);
339                 tty->canon_head = tty->read_tail;
340                 tty->canon_data = 0;
341                 tty->erasing = 0;
342         }
343         
344         
345         if (canon_change && !L_ICANON(tty) && tty->read_cnt)
346                 /* Get characters left over from canonical mode. */
347                 wake_up_interruptible(&tty->read_wait);
348
349         /* See if packet mode change of state. */
350
351         if (tty->link && tty->link->packet) {
352                 int old_flow = ((old_termios.c_iflag & IXON) &&
353                                 (old_termios.c_cc[VSTOP] == '\023') &&
354                                 (old_termios.c_cc[VSTART] == '\021'));
355                 int new_flow = (I_IXON(tty) &&
356                                 STOP_CHAR(tty) == '\023' &&
357                                 START_CHAR(tty) == '\021');
358                 if (old_flow != new_flow) {
359                         tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
360                         if (new_flow)
361                                 tty->ctrl_status |= TIOCPKT_DOSTOP;
362                         else
363                                 tty->ctrl_status |= TIOCPKT_NOSTOP;
364                         wake_up_interruptible(&tty->link->read_wait);
365                 }
366         }
367            
368         if (tty->driver->set_termios)
369                 (*tty->driver->set_termios)(tty, &old_termios);
370
371         ld = tty_ldisc_ref(tty);
372         if (ld != NULL) {
373                 if (ld->set_termios)
374                         (ld->set_termios)(tty, &old_termios);
375                 tty_ldisc_deref(ld);
376         }
377         mutex_unlock(&tty->termios_mutex);
378 }
379
380 /**
381  *      set_termios             -       set termios values for a tty
382  *      @tty: terminal device
383  *      @arg: user data
384  *      @opt: option information
385  *
386  *      Helper function to prepare termios data and run neccessary other
387  *      functions before using change_termios to do the actual changes.
388  *
389  *      Locking:
390  *              Called functions take ldisc and termios_sem locks
391  */
392
393 static int set_termios(struct tty_struct * tty, void __user *arg, int opt)
394 {
395         struct ktermios tmp_termios;
396         struct tty_ldisc *ld;
397         int retval = tty_check_change(tty);
398
399         if (retval)
400                 return retval;
401
402         memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
403
404         if (opt & TERMIOS_TERMIO) {
405                 if (user_termio_to_kernel_termios(&tmp_termios,
406                                                 (struct termio __user *)arg))
407                         return -EFAULT;
408 #ifdef TCGETS2
409         } else if (opt & TERMIOS_OLD) {
410                 if (user_termios_to_kernel_termios_1(&tmp_termios,
411                                                 (struct termios __user *)arg))
412                         return -EFAULT;
413         } else {
414                 if (user_termios_to_kernel_termios(&tmp_termios,
415                                                 (struct termios2 __user *)arg))
416                         return -EFAULT;
417         }
418 #else
419         } else if (user_termios_to_kernel_termios(&tmp_termios,
420                                         (struct termios __user *)arg))
421                 return -EFAULT;
422 #endif
423
424         /* If old style Bfoo values are used then load c_ispeed/c_ospeed with the real speed
425            so its unconditionally usable */
426         tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
427         tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
428
429         ld = tty_ldisc_ref(tty);
430         
431         if (ld != NULL) {
432                 if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
433                         ld->flush_buffer(tty);
434                 tty_ldisc_deref(ld);
435         }
436         
437         if (opt & TERMIOS_WAIT) {
438                 tty_wait_until_sent(tty, 0);
439                 if (signal_pending(current))
440                         return -EINTR;
441         }
442
443         change_termios(tty, &tmp_termios);
444         return 0;
445 }
446
447 static int get_termio(struct tty_struct * tty, struct termio __user * termio)
448 {
449         if (kernel_termios_to_user_termio(termio, tty->termios))
450                 return -EFAULT;
451         return 0;
452 }
453
454 static unsigned long inq_canon(struct tty_struct * tty)
455 {
456         int nr, head, tail;
457
458         if (!tty->canon_data || !tty->read_buf)
459                 return 0;
460         head = tty->canon_head;
461         tail = tty->read_tail;
462         nr = (head - tail) & (N_TTY_BUF_SIZE-1);
463         /* Skip EOF-chars.. */
464         while (head != tail) {
465                 if (test_bit(tail, tty->read_flags) &&
466                     tty->read_buf[tail] == __DISABLED_CHAR)
467                         nr--;
468                 tail = (tail+1) & (N_TTY_BUF_SIZE-1);
469         }
470         return nr;
471 }
472
473 #ifdef TIOCGETP
474 /*
475  * These are deprecated, but there is limited support..
476  *
477  * The "sg_flags" translation is a joke..
478  */
479 static int get_sgflags(struct tty_struct * tty)
480 {
481         int flags = 0;
482
483         if (!(tty->termios->c_lflag & ICANON)) {
484                 if (tty->termios->c_lflag & ISIG)
485                         flags |= 0x02;          /* cbreak */
486                 else
487                         flags |= 0x20;          /* raw */
488         }
489         if (tty->termios->c_lflag & ECHO)
490                 flags |= 0x08;                  /* echo */
491         if (tty->termios->c_oflag & OPOST)
492                 if (tty->termios->c_oflag & ONLCR)
493                         flags |= 0x10;          /* crmod */
494         return flags;
495 }
496
497 static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
498 {
499         struct sgttyb tmp;
500
501         mutex_lock(&tty->termios_mutex);
502         tmp.sg_ispeed = tty->termios->c_ispeed;
503         tmp.sg_ospeed = tty->termios->c_ospeed;
504         tmp.sg_erase = tty->termios->c_cc[VERASE];
505         tmp.sg_kill = tty->termios->c_cc[VKILL];
506         tmp.sg_flags = get_sgflags(tty);
507         mutex_unlock(&tty->termios_mutex);
508         
509         return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
510 }
511
512 static void set_sgflags(struct ktermios * termios, int flags)
513 {
514         termios->c_iflag = ICRNL | IXON;
515         termios->c_oflag = 0;
516         termios->c_lflag = ISIG | ICANON;
517         if (flags & 0x02) {     /* cbreak */
518                 termios->c_iflag = 0;
519                 termios->c_lflag &= ~ICANON;
520         }
521         if (flags & 0x08) {             /* echo */
522                 termios->c_lflag |= ECHO | ECHOE | ECHOK |
523                                     ECHOCTL | ECHOKE | IEXTEN;
524         }
525         if (flags & 0x10) {             /* crmod */
526                 termios->c_oflag |= OPOST | ONLCR;
527         }
528         if (flags & 0x20) {     /* raw */
529                 termios->c_iflag = 0;
530                 termios->c_lflag &= ~(ISIG | ICANON);
531         }
532         if (!(termios->c_lflag & ICANON)) {
533                 termios->c_cc[VMIN] = 1;
534                 termios->c_cc[VTIME] = 0;
535         }
536 }
537
538 /**
539  *      set_sgttyb              -       set legacy terminal values
540  *      @tty: tty structure
541  *      @sgttyb: pointer to old style terminal structure
542  *
543  *      Updates a terminal from the legacy BSD style terminal information
544  *      structure.
545  *
546  *      Locking: termios_sem
547  */
548
549 static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
550 {
551         int retval;
552         struct sgttyb tmp;
553         struct ktermios termios;
554
555         retval = tty_check_change(tty);
556         if (retval)
557                 return retval;
558         
559         if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
560                 return -EFAULT;
561
562         mutex_lock(&tty->termios_mutex);
563         termios =  *tty->termios;
564         termios.c_cc[VERASE] = tmp.sg_erase;
565         termios.c_cc[VKILL] = tmp.sg_kill;
566         set_sgflags(&termios, tmp.sg_flags);
567         /* Try and encode into Bfoo format */
568 #ifdef BOTHER
569         tty_termios_encode_baud_rate(&termios, termios.c_ispeed, termios.c_ospeed);
570 #endif
571         mutex_unlock(&tty->termios_mutex);
572         change_termios(tty, &termios);
573         return 0;
574 }
575 #endif
576
577 #ifdef TIOCGETC
578 static int get_tchars(struct tty_struct * tty, struct tchars __user * tchars)
579 {
580         struct tchars tmp;
581
582         tmp.t_intrc = tty->termios->c_cc[VINTR];
583         tmp.t_quitc = tty->termios->c_cc[VQUIT];
584         tmp.t_startc = tty->termios->c_cc[VSTART];
585         tmp.t_stopc = tty->termios->c_cc[VSTOP];
586         tmp.t_eofc = tty->termios->c_cc[VEOF];
587         tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
588         return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
589 }
590
591 static int set_tchars(struct tty_struct * tty, struct tchars __user * tchars)
592 {
593         struct tchars tmp;
594
595         if (copy_from_user(&tmp, tchars, sizeof(tmp)))
596                 return -EFAULT;
597         tty->termios->c_cc[VINTR] = tmp.t_intrc;
598         tty->termios->c_cc[VQUIT] = tmp.t_quitc;
599         tty->termios->c_cc[VSTART] = tmp.t_startc;
600         tty->termios->c_cc[VSTOP] = tmp.t_stopc;
601         tty->termios->c_cc[VEOF] = tmp.t_eofc;
602         tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
603         return 0;
604 }
605 #endif
606
607 #ifdef TIOCGLTC
608 static int get_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars)
609 {
610         struct ltchars tmp;
611
612         tmp.t_suspc = tty->termios->c_cc[VSUSP];
613         tmp.t_dsuspc = tty->termios->c_cc[VSUSP];       /* what is dsuspc anyway? */
614         tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
615         tmp.t_flushc = tty->termios->c_cc[VEOL2];       /* what is flushc anyway? */
616         tmp.t_werasc = tty->termios->c_cc[VWERASE];
617         tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
618         return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
619 }
620
621 static int set_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars)
622 {
623         struct ltchars tmp;
624
625         if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
626                 return -EFAULT;
627
628         tty->termios->c_cc[VSUSP] = tmp.t_suspc;
629         tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;       /* what is dsuspc anyway? */
630         tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
631         tty->termios->c_cc[VEOL2] = tmp.t_flushc;       /* what is flushc anyway? */
632         tty->termios->c_cc[VWERASE] = tmp.t_werasc;
633         tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
634         return 0;
635 }
636 #endif
637
638 /**
639  *      send_prio_char          -       send priority character
640  *
641  *      Send a high priority character to the tty even if stopped
642  *
643  *      Locking: none for xchar method, write ordering for write method.
644  */
645
646 static int send_prio_char(struct tty_struct *tty, char ch)
647 {
648         int     was_stopped = tty->stopped;
649
650         if (tty->driver->send_xchar) {
651                 tty->driver->send_xchar(tty, ch);
652                 return 0;
653         }
654
655         if (mutex_lock_interruptible(&tty->atomic_write_lock))
656                 return -ERESTARTSYS;
657
658         if (was_stopped)
659                 start_tty(tty);
660         tty->driver->write(tty, &ch, 1);
661         if (was_stopped)
662                 stop_tty(tty);
663         mutex_unlock(&tty->atomic_write_lock);
664         return 0;
665 }
666
667 int n_tty_ioctl(struct tty_struct * tty, struct file * file,
668                        unsigned int cmd, unsigned long arg)
669 {
670         struct tty_struct * real_tty;
671         void __user *p = (void __user *)arg;
672         int retval;
673         struct tty_ldisc *ld;
674
675         if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
676             tty->driver->subtype == PTY_TYPE_MASTER)
677                 real_tty = tty->link;
678         else
679                 real_tty = tty;
680
681         switch (cmd) {
682 #ifdef TIOCGETP
683                 case TIOCGETP:
684                         return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
685                 case TIOCSETP:
686                 case TIOCSETN:
687                         return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
688 #endif
689 #ifdef TIOCGETC
690                 case TIOCGETC:
691                         return get_tchars(real_tty, p);
692                 case TIOCSETC:
693                         return set_tchars(real_tty, p);
694 #endif
695 #ifdef TIOCGLTC
696                 case TIOCGLTC:
697                         return get_ltchars(real_tty, p);
698                 case TIOCSLTC:
699                         return set_ltchars(real_tty, p);
700 #endif
701                 case TCSETSF:
702                         return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
703                 case TCSETSW:
704                         return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
705                 case TCSETS:
706                         return set_termios(real_tty, p, TERMIOS_OLD);
707 #ifndef TCGETS2
708                 case TCGETS:
709                         if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
710                                 return -EFAULT;
711                         return 0;
712 #else
713                 case TCGETS:
714                         if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios))
715                                 return -EFAULT;
716                         return 0;
717                 case TCGETS2:
718                         if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios))
719                                 return -EFAULT;
720                         return 0;
721                 case TCSETSF2:
722                         return set_termios(real_tty, p,  TERMIOS_FLUSH | TERMIOS_WAIT);
723                 case TCSETSW2:
724                         return set_termios(real_tty, p, TERMIOS_WAIT);
725                 case TCSETS2:
726                         return set_termios(real_tty, p, 0);
727 #endif
728                 case TCGETA:
729                         return get_termio(real_tty, p);
730                 case TCSETAF:
731                         return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
732                 case TCSETAW:
733                         return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
734                 case TCSETA:
735                         return set_termios(real_tty, p, TERMIOS_TERMIO);
736                 case TCXONC:
737                         retval = tty_check_change(tty);
738                         if (retval)
739                                 return retval;
740                         switch (arg) {
741                         case TCOOFF:
742                                 if (!tty->flow_stopped) {
743                                         tty->flow_stopped = 1;
744                                         stop_tty(tty);
745                                 }
746                                 break;
747                         case TCOON:
748                                 if (tty->flow_stopped) {
749                                         tty->flow_stopped = 0;
750                                         start_tty(tty);
751                                 }
752                                 break;
753                         case TCIOFF:
754                                 if (STOP_CHAR(tty) != __DISABLED_CHAR)
755                                         return send_prio_char(tty, STOP_CHAR(tty));
756                                 break;
757                         case TCION:
758                                 if (START_CHAR(tty) != __DISABLED_CHAR)
759                                         return send_prio_char(tty, START_CHAR(tty));
760                                 break;
761                         default:
762                                 return -EINVAL;
763                         }
764                         return 0;
765                 case TCFLSH:
766                         retval = tty_check_change(tty);
767                         if (retval)
768                                 return retval;
769                                 
770                         ld = tty_ldisc_ref(tty);
771                         switch (arg) {
772                         case TCIFLUSH:
773                                 if (ld && ld->flush_buffer)
774                                         ld->flush_buffer(tty);
775                                 break;
776                         case TCIOFLUSH:
777                                 if (ld && ld->flush_buffer)
778                                         ld->flush_buffer(tty);
779                                 /* fall through */
780                         case TCOFLUSH:
781                                 if (tty->driver->flush_buffer)
782                                         tty->driver->flush_buffer(tty);
783                                 break;
784                         default:
785                                 tty_ldisc_deref(ld);
786                                 return -EINVAL;
787                         }
788                         tty_ldisc_deref(ld);
789                         return 0;
790                 case TIOCOUTQ:
791                         return put_user(tty->driver->chars_in_buffer ?
792                                         tty->driver->chars_in_buffer(tty) : 0,
793                                         (int __user *) arg);
794                 case TIOCINQ:
795                         retval = tty->read_cnt;
796                         if (L_ICANON(tty))
797                                 retval = inq_canon(tty);
798                         return put_user(retval, (unsigned int __user *) arg);
799                 case TIOCGLCKTRMIOS:
800                         if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
801                                 return -EFAULT;
802                         return 0;
803
804                 case TIOCSLCKTRMIOS:
805                         if (!capable(CAP_SYS_ADMIN))
806                                 return -EPERM;
807                         if (user_termios_to_kernel_termios(real_tty->termios_locked, (struct termios __user *) arg))
808                                 return -EFAULT;
809                         return 0;
810
811                 case TIOCPKT:
812                 {
813                         int pktmode;
814
815                         if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
816                             tty->driver->subtype != PTY_TYPE_MASTER)
817                                 return -ENOTTY;
818                         if (get_user(pktmode, (int __user *) arg))
819                                 return -EFAULT;
820                         if (pktmode) {
821                                 if (!tty->packet) {
822                                         tty->packet = 1;
823                                         tty->link->ctrl_status = 0;
824                                 }
825                         } else
826                                 tty->packet = 0;
827                         return 0;
828                 }
829                 case TIOCGSOFTCAR:
830                         return put_user(C_CLOCAL(tty) ? 1 : 0, (int __user *)arg);
831                 case TIOCSSOFTCAR:
832                         if (get_user(arg, (unsigned int __user *) arg))
833                                 return -EFAULT;
834                         mutex_lock(&tty->termios_mutex);
835                         tty->termios->c_cflag =
836                                 ((tty->termios->c_cflag & ~CLOCAL) |
837                                  (arg ? CLOCAL : 0));
838                         mutex_unlock(&tty->termios_mutex);
839                         return 0;
840                 default:
841                         return -ENOIOCTLCMD;
842                 }
843 }
844
845 EXPORT_SYMBOL(n_tty_ioctl);