1
2
3
4
5
6
7
8
9#include <linux/types.h>
10#include <linux/termios.h>
11#include <linux/errno.h>
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/major.h>
15#include <linux/tty.h>
16#include <linux/fcntl.h>
17#include <linux/string.h>
18#include <linux/mm.h>
19#include <linux/module.h>
20#include <linux/bitops.h>
21#include <linux/mutex.h>
22#include <linux/compat.h>
23
24#include <asm/io.h>
25#include <asm/uaccess.h>
26#include <asm/system.h>
27
28#undef TTY_DEBUG_WAIT_UNTIL_SENT
29
30#undef DEBUG
31
32
33
34
35#define TERMIOS_FLUSH 1
36#define TERMIOS_WAIT 2
37#define TERMIOS_TERMIO 4
38#define TERMIOS_OLD 8
39
40
41
42
43
44
45
46
47
48
49
50int tty_chars_in_buffer(struct tty_struct *tty)
51{
52 if (tty->ops->chars_in_buffer)
53 return tty->ops->chars_in_buffer(tty);
54 else
55 return 0;
56}
57EXPORT_SYMBOL(tty_chars_in_buffer);
58
59
60
61
62
63
64
65
66
67
68
69
70int tty_write_room(struct tty_struct *tty)
71{
72 if (tty->ops->write_room)
73 return tty->ops->write_room(tty);
74 return 2048;
75}
76EXPORT_SYMBOL(tty_write_room);
77
78
79
80
81
82
83
84
85
86void tty_driver_flush_buffer(struct tty_struct *tty)
87{
88 if (tty->ops->flush_buffer)
89 tty->ops->flush_buffer(tty);
90}
91EXPORT_SYMBOL(tty_driver_flush_buffer);
92
93
94
95
96
97
98
99
100
101
102
103void tty_throttle(struct tty_struct *tty)
104{
105 mutex_lock(&tty->termios_mutex);
106
107 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) &&
108 tty->ops->throttle)
109 tty->ops->throttle(tty);
110 mutex_unlock(&tty->termios_mutex);
111}
112EXPORT_SYMBOL(tty_throttle);
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127void tty_unthrottle(struct tty_struct *tty)
128{
129 mutex_lock(&tty->termios_mutex);
130 if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
131 tty->ops->unthrottle)
132 tty->ops->unthrottle(tty);
133 mutex_unlock(&tty->termios_mutex);
134}
135EXPORT_SYMBOL(tty_unthrottle);
136
137
138
139
140
141
142
143
144
145
146
147
148void tty_wait_until_sent(struct tty_struct *tty, long timeout)
149{
150#ifdef TTY_DEBUG_WAIT_UNTIL_SENT
151 char buf[64];
152
153 printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
154#endif
155 if (!timeout)
156 timeout = MAX_SCHEDULE_TIMEOUT;
157 if (wait_event_interruptible_timeout(tty->write_wait,
158 !tty_chars_in_buffer(tty), timeout) >= 0) {
159 if (tty->ops->wait_until_sent)
160 tty->ops->wait_until_sent(tty, timeout);
161 }
162}
163EXPORT_SYMBOL(tty_wait_until_sent);
164
165
166
167
168
169
170static void unset_locked_termios(struct ktermios *termios,
171 struct ktermios *old,
172 struct ktermios *locked)
173{
174 int i;
175
176#define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
177
178 if (!locked) {
179 printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
180 return;
181 }
182
183 NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
184 NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
185 NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
186 NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
187 termios->c_line = locked->c_line ? old->c_line : termios->c_line;
188 for (i = 0; i < NCCS; i++)
189 termios->c_cc[i] = locked->c_cc[i] ?
190 old->c_cc[i] : termios->c_cc[i];
191
192}
193
194
195
196
197
198
199
200static const speed_t baud_table[] = {
201 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
202 9600, 19200, 38400, 57600, 115200, 230400, 460800,
203#ifdef __sparc__
204 76800, 153600, 307200, 614400, 921600
205#else
206 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
207 2500000, 3000000, 3500000, 4000000
208#endif
209};
210
211#ifndef __sparc__
212static const tcflag_t baud_bits[] = {
213 B0, B50, B75, B110, B134, B150, B200, B300, B600,
214 B1200, B1800, B2400, B4800, B9600, B19200, B38400,
215 B57600, B115200, B230400, B460800, B500000, B576000,
216 B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
217 B3000000, B3500000, B4000000
218};
219#else
220static const tcflag_t baud_bits[] = {
221 B0, B50, B75, B110, B134, B150, B200, B300, B600,
222 B1200, B1800, B2400, B4800, B9600, B19200, B38400,
223 B57600, B115200, B230400, B460800, B76800, B153600,
224 B307200, B614400, B921600
225};
226#endif
227
228static int n_baud_table = ARRAY_SIZE(baud_table);
229
230
231
232
233
234
235
236
237
238
239
240
241
242speed_t tty_termios_baud_rate(struct ktermios *termios)
243{
244 unsigned int cbaud;
245
246 cbaud = termios->c_cflag & CBAUD;
247
248#ifdef BOTHER
249
250 if (cbaud == BOTHER)
251 return termios->c_ospeed;
252#endif
253 if (cbaud & CBAUDEX) {
254 cbaud &= ~CBAUDEX;
255
256 if (cbaud < 1 || cbaud + 15 > n_baud_table)
257 termios->c_cflag &= ~CBAUDEX;
258 else
259 cbaud += 15;
260 }
261 return baud_table[cbaud];
262}
263EXPORT_SYMBOL(tty_termios_baud_rate);
264
265
266
267
268
269
270
271
272
273
274
275
276
277speed_t tty_termios_input_baud_rate(struct ktermios *termios)
278{
279#ifdef IBSHIFT
280 unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
281
282 if (cbaud == B0)
283 return tty_termios_baud_rate(termios);
284
285
286 if (cbaud == BOTHER)
287 return termios->c_ispeed;
288
289 if (cbaud & CBAUDEX) {
290 cbaud &= ~CBAUDEX;
291
292 if (cbaud < 1 || cbaud + 15 > n_baud_table)
293 termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
294 else
295 cbaud += 15;
296 }
297 return baud_table[cbaud];
298#else
299 return tty_termios_baud_rate(termios);
300#endif
301}
302EXPORT_SYMBOL(tty_termios_input_baud_rate);
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326void tty_termios_encode_baud_rate(struct ktermios *termios,
327 speed_t ibaud, speed_t obaud)
328{
329 int i = 0;
330 int ifound = -1, ofound = -1;
331 int iclose = ibaud/50, oclose = obaud/50;
332 int ibinput = 0;
333
334 if (obaud == 0)
335 ibaud = 0;
336
337 termios->c_ispeed = ibaud;
338 termios->c_ospeed = obaud;
339
340#ifdef BOTHER
341
342
343
344
345 if ((termios->c_cflag & CBAUD) == BOTHER)
346 oclose = 0;
347 if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER)
348 iclose = 0;
349 if ((termios->c_cflag >> IBSHIFT) & CBAUD)
350 ibinput = 1;
351#endif
352 termios->c_cflag &= ~CBAUD;
353
354
355
356
357
358
359
360
361 do {
362 if (obaud - oclose <= baud_table[i] &&
363 obaud + oclose >= baud_table[i]) {
364 termios->c_cflag |= baud_bits[i];
365 ofound = i;
366 }
367 if (ibaud - iclose <= baud_table[i] &&
368 ibaud + iclose >= baud_table[i]) {
369
370
371 if (ofound == i && !ibinput)
372 ifound = i;
373#ifdef IBSHIFT
374 else {
375 ifound = i;
376 termios->c_cflag |= (baud_bits[i] << IBSHIFT);
377 }
378#endif
379 }
380 } while (++i < n_baud_table);
381
382
383
384
385
386#ifdef BOTHER
387 if (ofound == -1)
388 termios->c_cflag |= BOTHER;
389
390
391 if (ifound == -1 && (ibaud != obaud || ibinput))
392 termios->c_cflag |= (BOTHER << IBSHIFT);
393#else
394 if (ifound == -1 || ofound == -1) {
395 printk_once(KERN_WARNING "tty: Unable to return correct "
396 "speed data as your architecture needs updating.\n");
397 }
398#endif
399}
400EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
401
402
403
404
405
406
407
408
409
410
411
412void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
413{
414 tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
415}
416EXPORT_SYMBOL_GPL(tty_encode_baud_rate);
417
418
419
420
421
422
423
424
425
426
427
428
429speed_t tty_get_baud_rate(struct tty_struct *tty)
430{
431 speed_t baud = tty_termios_baud_rate(tty->termios);
432
433 if (baud == 38400 && tty->alt_speed) {
434 if (!tty->warned) {
435 printk(KERN_WARNING "Use of setserial/setrocket to "
436 "set SPD_* flags is deprecated\n");
437 tty->warned = 1;
438 }
439 baud = tty->alt_speed;
440 }
441
442 return baud;
443}
444EXPORT_SYMBOL(tty_get_baud_rate);
445
446
447
448
449
450
451
452
453
454
455
456
457void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old)
458{
459
460
461 new->c_cflag &= HUPCL | CREAD | CLOCAL;
462 new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL);
463 new->c_ispeed = old->c_ispeed;
464 new->c_ospeed = old->c_ospeed;
465}
466EXPORT_SYMBOL(tty_termios_copy_hw);
467
468
469
470
471
472
473
474
475
476
477int tty_termios_hw_change(struct ktermios *a, struct ktermios *b)
478{
479 if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
480 return 1;
481 if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL))
482 return 1;
483 return 0;
484}
485EXPORT_SYMBOL(tty_termios_hw_change);
486
487
488
489
490
491
492
493
494
495
496
497
498
499int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
500{
501 struct ktermios old_termios;
502 struct tty_ldisc *ld;
503 unsigned long flags;
504
505
506
507
508
509
510
511
512 mutex_lock(&tty->termios_mutex);
513 old_termios = *tty->termios;
514 *tty->termios = *new_termios;
515 unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
516
517
518 if (tty->link && tty->link->packet) {
519 int extproc = (old_termios.c_lflag & EXTPROC) |
520 (tty->termios->c_lflag & EXTPROC);
521 int old_flow = ((old_termios.c_iflag & IXON) &&
522 (old_termios.c_cc[VSTOP] == '\023') &&
523 (old_termios.c_cc[VSTART] == '\021'));
524 int new_flow = (I_IXON(tty) &&
525 STOP_CHAR(tty) == '\023' &&
526 START_CHAR(tty) == '\021');
527 if ((old_flow != new_flow) || extproc) {
528 spin_lock_irqsave(&tty->ctrl_lock, flags);
529 if (old_flow != new_flow) {
530 tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
531 if (new_flow)
532 tty->ctrl_status |= TIOCPKT_DOSTOP;
533 else
534 tty->ctrl_status |= TIOCPKT_NOSTOP;
535 }
536 if (extproc)
537 tty->ctrl_status |= TIOCPKT_IOCTL;
538 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
539 wake_up_interruptible(&tty->link->read_wait);
540 }
541 }
542
543 if (tty->ops->set_termios)
544 (*tty->ops->set_termios)(tty, &old_termios);
545 else
546 tty_termios_copy_hw(tty->termios, &old_termios);
547
548 ld = tty_ldisc_ref(tty);
549 if (ld != NULL) {
550 if (ld->ops->set_termios)
551 (ld->ops->set_termios)(tty, &old_termios);
552 tty_ldisc_deref(ld);
553 }
554 mutex_unlock(&tty->termios_mutex);
555 return 0;
556}
557EXPORT_SYMBOL_GPL(tty_set_termios);
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
573{
574 struct ktermios tmp_termios;
575 struct tty_ldisc *ld;
576 int retval = tty_check_change(tty);
577
578 if (retval)
579 return retval;
580
581 mutex_lock(&tty->termios_mutex);
582 memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
583 mutex_unlock(&tty->termios_mutex);
584
585 if (opt & TERMIOS_TERMIO) {
586 if (user_termio_to_kernel_termios(&tmp_termios,
587 (struct termio __user *)arg))
588 return -EFAULT;
589#ifdef TCGETS2
590 } else if (opt & TERMIOS_OLD) {
591 if (user_termios_to_kernel_termios_1(&tmp_termios,
592 (struct termios __user *)arg))
593 return -EFAULT;
594 } else {
595 if (user_termios_to_kernel_termios(&tmp_termios,
596 (struct termios2 __user *)arg))
597 return -EFAULT;
598 }
599#else
600 } else if (user_termios_to_kernel_termios(&tmp_termios,
601 (struct termios __user *)arg))
602 return -EFAULT;
603#endif
604
605
606
607 tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
608 tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
609
610 ld = tty_ldisc_ref(tty);
611
612 if (ld != NULL) {
613 if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
614 ld->ops->flush_buffer(tty);
615 tty_ldisc_deref(ld);
616 }
617
618 if (opt & TERMIOS_WAIT) {
619 tty_wait_until_sent(tty, 0);
620 if (signal_pending(current))
621 return -EINTR;
622 }
623
624 tty_set_termios(tty, &tmp_termios);
625
626
627
628
629
630 return 0;
631}
632
633static void copy_termios(struct tty_struct *tty, struct ktermios *kterm)
634{
635 mutex_lock(&tty->termios_mutex);
636 memcpy(kterm, tty->termios, sizeof(struct ktermios));
637 mutex_unlock(&tty->termios_mutex);
638}
639
640static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm)
641{
642 mutex_lock(&tty->termios_mutex);
643 memcpy(kterm, tty->termios_locked, sizeof(struct ktermios));
644 mutex_unlock(&tty->termios_mutex);
645}
646
647static int get_termio(struct tty_struct *tty, struct termio __user *termio)
648{
649 struct ktermios kterm;
650 copy_termios(tty, &kterm);
651 if (kernel_termios_to_user_termio(termio, &kterm))
652 return -EFAULT;
653 return 0;
654}
655
656
657#ifdef TCGETX
658
659
660
661
662
663
664
665
666
667
668
669static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
670{
671 struct termiox tnew;
672 struct tty_ldisc *ld;
673
674 if (tty->termiox == NULL)
675 return -EINVAL;
676 if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
677 return -EFAULT;
678
679 ld = tty_ldisc_ref(tty);
680 if (ld != NULL) {
681 if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
682 ld->ops->flush_buffer(tty);
683 tty_ldisc_deref(ld);
684 }
685 if (opt & TERMIOS_WAIT) {
686 tty_wait_until_sent(tty, 0);
687 if (signal_pending(current))
688 return -EINTR;
689 }
690
691 mutex_lock(&tty->termios_mutex);
692 if (tty->ops->set_termiox)
693 tty->ops->set_termiox(tty, &tnew);
694 mutex_unlock(&tty->termios_mutex);
695 return 0;
696}
697
698#endif
699
700
701#ifdef TIOCGETP
702
703
704
705
706
707static int get_sgflags(struct tty_struct *tty)
708{
709 int flags = 0;
710
711 if (!(tty->termios->c_lflag & ICANON)) {
712 if (tty->termios->c_lflag & ISIG)
713 flags |= 0x02;
714 else
715 flags |= 0x20;
716 }
717 if (tty->termios->c_lflag & ECHO)
718 flags |= 0x08;
719 if (tty->termios->c_oflag & OPOST)
720 if (tty->termios->c_oflag & ONLCR)
721 flags |= 0x10;
722 return flags;
723}
724
725static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
726{
727 struct sgttyb tmp;
728
729 mutex_lock(&tty->termios_mutex);
730 tmp.sg_ispeed = tty->termios->c_ispeed;
731 tmp.sg_ospeed = tty->termios->c_ospeed;
732 tmp.sg_erase = tty->termios->c_cc[VERASE];
733 tmp.sg_kill = tty->termios->c_cc[VKILL];
734 tmp.sg_flags = get_sgflags(tty);
735 mutex_unlock(&tty->termios_mutex);
736
737 return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
738}
739
740static void set_sgflags(struct ktermios *termios, int flags)
741{
742 termios->c_iflag = ICRNL | IXON;
743 termios->c_oflag = 0;
744 termios->c_lflag = ISIG | ICANON;
745 if (flags & 0x02) {
746 termios->c_iflag = 0;
747 termios->c_lflag &= ~ICANON;
748 }
749 if (flags & 0x08) {
750 termios->c_lflag |= ECHO | ECHOE | ECHOK |
751 ECHOCTL | ECHOKE | IEXTEN;
752 }
753 if (flags & 0x10) {
754 termios->c_oflag |= OPOST | ONLCR;
755 }
756 if (flags & 0x20) {
757 termios->c_iflag = 0;
758 termios->c_lflag &= ~(ISIG | ICANON);
759 }
760 if (!(termios->c_lflag & ICANON)) {
761 termios->c_cc[VMIN] = 1;
762 termios->c_cc[VTIME] = 0;
763 }
764}
765
766
767
768
769
770
771
772
773
774
775
776
777static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
778{
779 int retval;
780 struct sgttyb tmp;
781 struct ktermios termios;
782
783 retval = tty_check_change(tty);
784 if (retval)
785 return retval;
786
787 if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
788 return -EFAULT;
789
790 mutex_lock(&tty->termios_mutex);
791 termios = *tty->termios;
792 termios.c_cc[VERASE] = tmp.sg_erase;
793 termios.c_cc[VKILL] = tmp.sg_kill;
794 set_sgflags(&termios, tmp.sg_flags);
795
796#ifdef BOTHER
797 tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
798 termios.c_ospeed);
799#endif
800 mutex_unlock(&tty->termios_mutex);
801 tty_set_termios(tty, &termios);
802 return 0;
803}
804#endif
805
806#ifdef TIOCGETC
807static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
808{
809 struct tchars tmp;
810
811 mutex_lock(&tty->termios_mutex);
812 tmp.t_intrc = tty->termios->c_cc[VINTR];
813 tmp.t_quitc = tty->termios->c_cc[VQUIT];
814 tmp.t_startc = tty->termios->c_cc[VSTART];
815 tmp.t_stopc = tty->termios->c_cc[VSTOP];
816 tmp.t_eofc = tty->termios->c_cc[VEOF];
817 tmp.t_brkc = tty->termios->c_cc[VEOL2];
818 mutex_unlock(&tty->termios_mutex);
819 return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
820}
821
822static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
823{
824 struct tchars tmp;
825
826 if (copy_from_user(&tmp, tchars, sizeof(tmp)))
827 return -EFAULT;
828 mutex_lock(&tty->termios_mutex);
829 tty->termios->c_cc[VINTR] = tmp.t_intrc;
830 tty->termios->c_cc[VQUIT] = tmp.t_quitc;
831 tty->termios->c_cc[VSTART] = tmp.t_startc;
832 tty->termios->c_cc[VSTOP] = tmp.t_stopc;
833 tty->termios->c_cc[VEOF] = tmp.t_eofc;
834 tty->termios->c_cc[VEOL2] = tmp.t_brkc;
835 mutex_unlock(&tty->termios_mutex);
836 return 0;
837}
838#endif
839
840#ifdef TIOCGLTC
841static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
842{
843 struct ltchars tmp;
844
845 mutex_lock(&tty->termios_mutex);
846 tmp.t_suspc = tty->termios->c_cc[VSUSP];
847
848 tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
849 tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
850
851 tmp.t_flushc = tty->termios->c_cc[VEOL2];
852 tmp.t_werasc = tty->termios->c_cc[VWERASE];
853 tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
854 mutex_unlock(&tty->termios_mutex);
855 return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
856}
857
858static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
859{
860 struct ltchars tmp;
861
862 if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
863 return -EFAULT;
864
865 mutex_lock(&tty->termios_mutex);
866 tty->termios->c_cc[VSUSP] = tmp.t_suspc;
867
868 tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
869 tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
870
871 tty->termios->c_cc[VEOL2] = tmp.t_flushc;
872 tty->termios->c_cc[VWERASE] = tmp.t_werasc;
873 tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
874 mutex_unlock(&tty->termios_mutex);
875 return 0;
876}
877#endif
878
879
880
881
882
883
884
885
886
887static int send_prio_char(struct tty_struct *tty, char ch)
888{
889 int was_stopped = tty->stopped;
890
891 if (tty->ops->send_xchar) {
892 tty->ops->send_xchar(tty, ch);
893 return 0;
894 }
895
896 if (tty_write_lock(tty, 0) < 0)
897 return -ERESTARTSYS;
898
899 if (was_stopped)
900 start_tty(tty);
901 tty->ops->write(tty, &ch, 1);
902 if (was_stopped)
903 stop_tty(tty);
904 tty_write_unlock(tty);
905 return 0;
906}
907
908
909
910
911
912
913
914
915
916
917static int tty_change_softcar(struct tty_struct *tty, int arg)
918{
919 int ret = 0;
920 int bit = arg ? CLOCAL : 0;
921 struct ktermios old;
922
923 mutex_lock(&tty->termios_mutex);
924 old = *tty->termios;
925 tty->termios->c_cflag &= ~CLOCAL;
926 tty->termios->c_cflag |= bit;
927 if (tty->ops->set_termios)
928 tty->ops->set_termios(tty, &old);
929 if ((tty->termios->c_cflag & CLOCAL) != bit)
930 ret = -EINVAL;
931 mutex_unlock(&tty->termios_mutex);
932 return ret;
933}
934
935
936
937
938
939
940
941
942
943
944
945
946
947int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
948 unsigned int cmd, unsigned long arg)
949{
950 struct tty_struct *real_tty;
951 void __user *p = (void __user *)arg;
952 int ret = 0;
953 struct ktermios kterm;
954
955 BUG_ON(file == NULL);
956
957 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
958 tty->driver->subtype == PTY_TYPE_MASTER)
959 real_tty = tty->link;
960 else
961 real_tty = tty;
962
963 switch (cmd) {
964#ifdef TIOCGETP
965 case TIOCGETP:
966 return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
967 case TIOCSETP:
968 case TIOCSETN:
969 return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
970#endif
971#ifdef TIOCGETC
972 case TIOCGETC:
973 return get_tchars(real_tty, p);
974 case TIOCSETC:
975 return set_tchars(real_tty, p);
976#endif
977#ifdef TIOCGLTC
978 case TIOCGLTC:
979 return get_ltchars(real_tty, p);
980 case TIOCSLTC:
981 return set_ltchars(real_tty, p);
982#endif
983 case TCSETSF:
984 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
985 case TCSETSW:
986 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
987 case TCSETS:
988 return set_termios(real_tty, p, TERMIOS_OLD);
989#ifndef TCGETS2
990 case TCGETS:
991 copy_termios(real_tty, &kterm);
992 if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
993 ret = -EFAULT;
994 return ret;
995#else
996 case TCGETS:
997 copy_termios(real_tty, &kterm);
998 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
999 ret = -EFAULT;
1000 return ret;
1001 case TCGETS2:
1002 copy_termios(real_tty, &kterm);
1003 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm))
1004 ret = -EFAULT;
1005 return ret;
1006 case TCSETSF2:
1007 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT);
1008 case TCSETSW2:
1009 return set_termios(real_tty, p, TERMIOS_WAIT);
1010 case TCSETS2:
1011 return set_termios(real_tty, p, 0);
1012#endif
1013 case TCGETA:
1014 return get_termio(real_tty, p);
1015 case TCSETAF:
1016 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
1017 case TCSETAW:
1018 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
1019 case TCSETA:
1020 return set_termios(real_tty, p, TERMIOS_TERMIO);
1021#ifndef TCGETS2
1022 case TIOCGLCKTRMIOS:
1023 copy_termios_locked(real_tty, &kterm);
1024 if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
1025 ret = -EFAULT;
1026 return ret;
1027 case TIOCSLCKTRMIOS:
1028 if (!capable(CAP_SYS_ADMIN))
1029 return -EPERM;
1030 copy_termios_locked(real_tty, &kterm);
1031 if (user_termios_to_kernel_termios(&kterm,
1032 (struct termios __user *) arg))
1033 return -EFAULT;
1034 mutex_lock(&real_tty->termios_mutex);
1035 memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
1036 mutex_unlock(&real_tty->termios_mutex);
1037 return 0;
1038#else
1039 case TIOCGLCKTRMIOS:
1040 copy_termios_locked(real_tty, &kterm);
1041 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
1042 ret = -EFAULT;
1043 return ret;
1044 case TIOCSLCKTRMIOS:
1045 if (!capable(CAP_SYS_ADMIN))
1046 return -EPERM;
1047 copy_termios_locked(real_tty, &kterm);
1048 if (user_termios_to_kernel_termios_1(&kterm,
1049 (struct termios __user *) arg))
1050 return -EFAULT;
1051 mutex_lock(&real_tty->termios_mutex);
1052 memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
1053 mutex_unlock(&real_tty->termios_mutex);
1054 return ret;
1055#endif
1056#ifdef TCGETX
1057 case TCGETX: {
1058 struct termiox ktermx;
1059 if (real_tty->termiox == NULL)
1060 return -EINVAL;
1061 mutex_lock(&real_tty->termios_mutex);
1062 memcpy(&ktermx, real_tty->termiox, sizeof(struct termiox));
1063 mutex_unlock(&real_tty->termios_mutex);
1064 if (copy_to_user(p, &ktermx, sizeof(struct termiox)))
1065 ret = -EFAULT;
1066 return ret;
1067 }
1068 case TCSETX:
1069 return set_termiox(real_tty, p, 0);
1070 case TCSETXW:
1071 return set_termiox(real_tty, p, TERMIOS_WAIT);
1072 case TCSETXF:
1073 return set_termiox(real_tty, p, TERMIOS_FLUSH);
1074#endif
1075 case TIOCGSOFTCAR:
1076 copy_termios(real_tty, &kterm);
1077 ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0,
1078 (int __user *)arg);
1079 return ret;
1080 case TIOCSSOFTCAR:
1081 if (get_user(arg, (unsigned int __user *) arg))
1082 return -EFAULT;
1083 return tty_change_softcar(real_tty, arg);
1084 default:
1085 return -ENOIOCTLCMD;
1086 }
1087}
1088EXPORT_SYMBOL_GPL(tty_mode_ioctl);
1089
1090int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
1091{
1092 struct tty_ldisc *ld;
1093 int retval = tty_check_change(tty);
1094 if (retval)
1095 return retval;
1096
1097 ld = tty_ldisc_ref_wait(tty);
1098 switch (arg) {
1099 case TCIFLUSH:
1100 if (ld && ld->ops->flush_buffer)
1101 ld->ops->flush_buffer(tty);
1102 break;
1103 case TCIOFLUSH:
1104 if (ld && ld->ops->flush_buffer)
1105 ld->ops->flush_buffer(tty);
1106
1107 case TCOFLUSH:
1108 tty_driver_flush_buffer(tty);
1109 break;
1110 default:
1111 tty_ldisc_deref(ld);
1112 return -EINVAL;
1113 }
1114 tty_ldisc_deref(ld);
1115 return 0;
1116}
1117EXPORT_SYMBOL_GPL(tty_perform_flush);
1118
1119int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file,
1120 unsigned int cmd, unsigned long arg)
1121{
1122 unsigned long flags;
1123 int retval;
1124
1125 switch (cmd) {
1126 case TCXONC:
1127 retval = tty_check_change(tty);
1128 if (retval)
1129 return retval;
1130 switch (arg) {
1131 case TCOOFF:
1132 if (!tty->flow_stopped) {
1133 tty->flow_stopped = 1;
1134 stop_tty(tty);
1135 }
1136 break;
1137 case TCOON:
1138 if (tty->flow_stopped) {
1139 tty->flow_stopped = 0;
1140 start_tty(tty);
1141 }
1142 break;
1143 case TCIOFF:
1144 if (STOP_CHAR(tty) != __DISABLED_CHAR)
1145 return send_prio_char(tty, STOP_CHAR(tty));
1146 break;
1147 case TCION:
1148 if (START_CHAR(tty) != __DISABLED_CHAR)
1149 return send_prio_char(tty, START_CHAR(tty));
1150 break;
1151 default:
1152 return -EINVAL;
1153 }
1154 return 0;
1155 case TCFLSH:
1156 return tty_perform_flush(tty, arg);
1157 case TIOCPKT:
1158 {
1159 int pktmode;
1160
1161 if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
1162 tty->driver->subtype != PTY_TYPE_MASTER)
1163 return -ENOTTY;
1164 if (get_user(pktmode, (int __user *) arg))
1165 return -EFAULT;
1166 spin_lock_irqsave(&tty->ctrl_lock, flags);
1167 if (pktmode) {
1168 if (!tty->packet) {
1169 tty->packet = 1;
1170 tty->link->ctrl_status = 0;
1171 }
1172 } else
1173 tty->packet = 0;
1174 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1175 return 0;
1176 }
1177 default:
1178
1179 return tty_mode_ioctl(tty, file, cmd, arg);
1180 }
1181}
1182EXPORT_SYMBOL(n_tty_ioctl_helper);
1183
1184#ifdef CONFIG_COMPAT
1185long n_tty_compat_ioctl_helper(struct tty_struct *tty, struct file *file,
1186 unsigned int cmd, unsigned long arg)
1187{
1188 switch (cmd) {
1189 case TIOCGLCKTRMIOS:
1190 case TIOCSLCKTRMIOS:
1191 return tty_mode_ioctl(tty, file, cmd, (unsigned long) compat_ptr(arg));
1192 default:
1193 return -ENOIOCTLCMD;
1194 }
1195}
1196EXPORT_SYMBOL(n_tty_compat_ioctl_helper);
1197#endif
1198
1199