1
2#include <linux/types.h>
3#include <linux/errno.h>
4#include <linux/kmod.h>
5#include <linux/sched.h>
6#include <linux/interrupt.h>
7#include <linux/tty.h>
8#include <linux/tty_driver.h>
9#include <linux/file.h>
10#include <linux/mm.h>
11#include <linux/string.h>
12#include <linux/slab.h>
13#include <linux/poll.h>
14#include <linux/proc_fs.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/wait.h>
18#include <linux/bitops.h>
19#include <linux/seq_file.h>
20#include <linux/uaccess.h>
21#include <linux/ratelimit.h>
22
23#undef LDISC_DEBUG_HANGUP
24
25#ifdef LDISC_DEBUG_HANGUP
26#define tty_ldisc_debug(tty, f, args...) tty_debug(tty, f, ##args)
27#else
28#define tty_ldisc_debug(tty, f, args...)
29#endif
30
31
32enum {
33 LDISC_SEM_NORMAL,
34 LDISC_SEM_OTHER,
35};
36
37
38
39
40
41
42
43
44static DEFINE_RAW_SPINLOCK(tty_ldiscs_lock);
45
46static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
62{
63 unsigned long flags;
64 int ret = 0;
65
66 if (disc < N_TTY || disc >= NR_LDISCS)
67 return -EINVAL;
68
69 raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
70 tty_ldiscs[disc] = new_ldisc;
71 new_ldisc->num = disc;
72 new_ldisc->refcount = 0;
73 raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
74
75 return ret;
76}
77EXPORT_SYMBOL(tty_register_ldisc);
78
79
80
81
82
83
84
85
86
87
88
89
90
91int tty_unregister_ldisc(int disc)
92{
93 unsigned long flags;
94 int ret = 0;
95
96 if (disc < N_TTY || disc >= NR_LDISCS)
97 return -EINVAL;
98
99 raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
100 if (tty_ldiscs[disc]->refcount)
101 ret = -EBUSY;
102 else
103 tty_ldiscs[disc] = NULL;
104 raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
105
106 return ret;
107}
108EXPORT_SYMBOL(tty_unregister_ldisc);
109
110static struct tty_ldisc_ops *get_ldops(int disc)
111{
112 unsigned long flags;
113 struct tty_ldisc_ops *ldops, *ret;
114
115 raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
116 ret = ERR_PTR(-EINVAL);
117 ldops = tty_ldiscs[disc];
118 if (ldops) {
119 ret = ERR_PTR(-EAGAIN);
120 if (try_module_get(ldops->owner)) {
121 ldops->refcount++;
122 ret = ldops;
123 }
124 }
125 raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
126 return ret;
127}
128
129static void put_ldops(struct tty_ldisc_ops *ldops)
130{
131 unsigned long flags;
132
133 raw_spin_lock_irqsave(&tty_ldiscs_lock, flags);
134 ldops->refcount--;
135 module_put(ldops->owner);
136 raw_spin_unlock_irqrestore(&tty_ldiscs_lock, flags);
137}
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc)
160{
161 struct tty_ldisc *ld;
162 struct tty_ldisc_ops *ldops;
163
164 if (disc < N_TTY || disc >= NR_LDISCS)
165 return ERR_PTR(-EINVAL);
166
167
168
169
170
171 ldops = get_ldops(disc);
172 if (IS_ERR(ldops)) {
173 request_module("tty-ldisc-%d", disc);
174 ldops = get_ldops(disc);
175 if (IS_ERR(ldops))
176 return ERR_CAST(ldops);
177 }
178
179 ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL);
180 if (ld == NULL) {
181 put_ldops(ldops);
182 return ERR_PTR(-ENOMEM);
183 }
184
185 ld->ops = ldops;
186 ld->tty = tty;
187
188 return ld;
189}
190
191
192
193
194
195
196static void tty_ldisc_put(struct tty_ldisc *ld)
197{
198 if (WARN_ON_ONCE(!ld))
199 return;
200
201 put_ldops(ld->ops);
202 kfree(ld);
203}
204
205static void *tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
206{
207 return (*pos < NR_LDISCS) ? pos : NULL;
208}
209
210static void *tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
211{
212 (*pos)++;
213 return (*pos < NR_LDISCS) ? pos : NULL;
214}
215
216static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
217{
218}
219
220static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
221{
222 int i = *(loff_t *)v;
223 struct tty_ldisc_ops *ldops;
224
225 ldops = get_ldops(i);
226 if (IS_ERR(ldops))
227 return 0;
228 seq_printf(m, "%-10s %2d\n", ldops->name ? ldops->name : "???", i);
229 put_ldops(ldops);
230 return 0;
231}
232
233static const struct seq_operations tty_ldiscs_seq_ops = {
234 .start = tty_ldiscs_seq_start,
235 .next = tty_ldiscs_seq_next,
236 .stop = tty_ldiscs_seq_stop,
237 .show = tty_ldiscs_seq_show,
238};
239
240static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
241{
242 return seq_open(file, &tty_ldiscs_seq_ops);
243}
244
245const struct file_operations tty_ldiscs_proc_fops = {
246 .owner = THIS_MODULE,
247 .open = proc_tty_ldiscs_open,
248 .read = seq_read,
249 .llseek = seq_lseek,
250 .release = seq_release,
251};
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273struct tty_ldisc *tty_ldisc_ref_wait(struct tty_struct *tty)
274{
275 struct tty_ldisc *ld;
276
277 ldsem_down_read(&tty->ldisc_sem, MAX_SCHEDULE_TIMEOUT);
278 ld = tty->ldisc;
279 if (!ld)
280 ldsem_up_read(&tty->ldisc_sem);
281 return ld;
282}
283EXPORT_SYMBOL_GPL(tty_ldisc_ref_wait);
284
285
286
287
288
289
290
291
292
293
294struct tty_ldisc *tty_ldisc_ref(struct tty_struct *tty)
295{
296 struct tty_ldisc *ld = NULL;
297
298 if (ldsem_down_read_trylock(&tty->ldisc_sem)) {
299 ld = tty->ldisc;
300 if (!ld)
301 ldsem_up_read(&tty->ldisc_sem);
302 }
303 return ld;
304}
305EXPORT_SYMBOL_GPL(tty_ldisc_ref);
306
307
308
309
310
311
312
313
314
315void tty_ldisc_deref(struct tty_ldisc *ld)
316{
317 ldsem_up_read(&ld->tty->ldisc_sem);
318}
319EXPORT_SYMBOL_GPL(tty_ldisc_deref);
320
321
322static inline int
323__tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
324{
325 return ldsem_down_write(&tty->ldisc_sem, timeout);
326}
327
328static inline int
329__tty_ldisc_lock_nested(struct tty_struct *tty, unsigned long timeout)
330{
331 return ldsem_down_write_nested(&tty->ldisc_sem,
332 LDISC_SEM_OTHER, timeout);
333}
334
335static inline void __tty_ldisc_unlock(struct tty_struct *tty)
336{
337 ldsem_up_write(&tty->ldisc_sem);
338}
339
340int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout)
341{
342 int ret;
343
344 ret = __tty_ldisc_lock(tty, timeout);
345 if (!ret)
346 return -EBUSY;
347 set_bit(TTY_LDISC_HALTED, &tty->flags);
348 return 0;
349}
350
351void tty_ldisc_unlock(struct tty_struct *tty)
352{
353 clear_bit(TTY_LDISC_HALTED, &tty->flags);
354 __tty_ldisc_unlock(tty);
355}
356
357static int
358tty_ldisc_lock_pair_timeout(struct tty_struct *tty, struct tty_struct *tty2,
359 unsigned long timeout)
360{
361 int ret;
362
363 if (tty < tty2) {
364 ret = __tty_ldisc_lock(tty, timeout);
365 if (ret) {
366 ret = __tty_ldisc_lock_nested(tty2, timeout);
367 if (!ret)
368 __tty_ldisc_unlock(tty);
369 }
370 } else {
371
372 WARN_ON_ONCE(tty == tty2);
373 if (tty2 && tty != tty2) {
374 ret = __tty_ldisc_lock(tty2, timeout);
375 if (ret) {
376 ret = __tty_ldisc_lock_nested(tty, timeout);
377 if (!ret)
378 __tty_ldisc_unlock(tty2);
379 }
380 } else
381 ret = __tty_ldisc_lock(tty, timeout);
382 }
383
384 if (!ret)
385 return -EBUSY;
386
387 set_bit(TTY_LDISC_HALTED, &tty->flags);
388 if (tty2)
389 set_bit(TTY_LDISC_HALTED, &tty2->flags);
390 return 0;
391}
392
393static void tty_ldisc_lock_pair(struct tty_struct *tty, struct tty_struct *tty2)
394{
395 tty_ldisc_lock_pair_timeout(tty, tty2, MAX_SCHEDULE_TIMEOUT);
396}
397
398static void tty_ldisc_unlock_pair(struct tty_struct *tty,
399 struct tty_struct *tty2)
400{
401 __tty_ldisc_unlock(tty);
402 if (tty2)
403 __tty_ldisc_unlock(tty2);
404}
405
406
407
408
409
410
411
412
413
414void tty_ldisc_flush(struct tty_struct *tty)
415{
416 struct tty_ldisc *ld = tty_ldisc_ref(tty);
417
418 tty_buffer_flush(tty, ld);
419 if (ld)
420 tty_ldisc_deref(ld);
421}
422EXPORT_SYMBOL_GPL(tty_ldisc_flush);
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440static void tty_set_termios_ldisc(struct tty_struct *tty, int disc)
441{
442 down_write(&tty->termios_rwsem);
443 tty->termios.c_line = disc;
444 up_write(&tty->termios_rwsem);
445
446 tty->disc_data = NULL;
447 tty->receive_room = 0;
448}
449
450
451
452
453
454
455
456
457
458
459
460
461static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
462{
463 WARN_ON(test_and_set_bit(TTY_LDISC_OPEN, &tty->flags));
464 if (ld->ops->open) {
465 int ret;
466
467 ret = ld->ops->open(tty);
468 if (ret)
469 clear_bit(TTY_LDISC_OPEN, &tty->flags);
470
471 tty_ldisc_debug(tty, "%p: opened\n", ld);
472 return ret;
473 }
474 return 0;
475}
476
477
478
479
480
481
482
483
484
485
486static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
487{
488 WARN_ON(!test_bit(TTY_LDISC_OPEN, &tty->flags));
489 clear_bit(TTY_LDISC_OPEN, &tty->flags);
490 if (ld->ops->close)
491 ld->ops->close(tty);
492 tty_ldisc_debug(tty, "%p: closed\n", ld);
493}
494
495
496
497
498
499
500
501
502
503
504static int tty_ldisc_failto(struct tty_struct *tty, int ld)
505{
506 struct tty_ldisc *disc = tty_ldisc_get(tty, ld);
507 int r;
508
509 if (IS_ERR(disc))
510 return PTR_ERR(disc);
511 tty->ldisc = disc;
512 tty_set_termios_ldisc(tty, ld);
513 if ((r = tty_ldisc_open(tty, disc)) < 0)
514 tty_ldisc_put(disc);
515 return r;
516}
517
518
519
520
521
522
523
524
525
526
527static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
528{
529
530 old = tty_ldisc_get(tty, old->ops->num);
531 WARN_ON(IS_ERR(old));
532 tty->ldisc = old;
533 tty_set_termios_ldisc(tty, old->ops->num);
534 if (tty_ldisc_open(tty, old) < 0) {
535 tty_ldisc_put(old);
536
537
538
539 if (tty_ldisc_failto(tty, N_TTY) < 0 &&
540 tty_ldisc_failto(tty, N_NULL) < 0)
541 panic("Couldn't open N_NULL ldisc for %s.",
542 tty_name(tty));
543 }
544}
545
546
547
548
549
550
551
552
553
554
555
556
557int tty_set_ldisc(struct tty_struct *tty, int disc)
558{
559 int retval;
560 struct tty_ldisc *old_ldisc, *new_ldisc;
561
562 new_ldisc = tty_ldisc_get(tty, disc);
563 if (IS_ERR(new_ldisc))
564 return PTR_ERR(new_ldisc);
565
566 tty_lock(tty);
567 retval = tty_ldisc_lock(tty, 5 * HZ);
568 if (retval)
569 goto err;
570
571 if (!tty->ldisc) {
572 retval = -EIO;
573 goto out;
574 }
575
576
577 if (tty->ldisc->ops->num == disc)
578 goto out;
579
580 if (test_bit(TTY_HUPPED, &tty->flags)) {
581
582 retval = -EIO;
583 goto out;
584 }
585
586 old_ldisc = tty->ldisc;
587
588
589 tty_ldisc_close(tty, old_ldisc);
590
591
592 tty->ldisc = new_ldisc;
593 tty_set_termios_ldisc(tty, disc);
594
595 retval = tty_ldisc_open(tty, new_ldisc);
596 if (retval < 0) {
597
598 tty_ldisc_put(new_ldisc);
599 tty_ldisc_restore(tty, old_ldisc);
600 }
601
602 if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) {
603 down_read(&tty->termios_rwsem);
604 tty->ops->set_ldisc(tty);
605 up_read(&tty->termios_rwsem);
606 }
607
608
609
610
611
612
613 new_ldisc = old_ldisc;
614out:
615 tty_ldisc_unlock(tty);
616
617
618
619 tty_buffer_restart_work(tty->port);
620err:
621 tty_ldisc_put(new_ldisc);
622 tty_unlock(tty);
623 return retval;
624}
625EXPORT_SYMBOL_GPL(tty_set_ldisc);
626
627
628
629
630
631
632
633static void tty_ldisc_kill(struct tty_struct *tty)
634{
635 if (!tty->ldisc)
636 return;
637
638
639
640 tty_ldisc_close(tty, tty->ldisc);
641 tty_ldisc_put(tty->ldisc);
642
643 tty->ldisc = NULL;
644}
645
646
647
648
649
650
651
652
653static void tty_reset_termios(struct tty_struct *tty)
654{
655 down_write(&tty->termios_rwsem);
656 tty->termios = tty->driver->init_termios;
657 tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios);
658 tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios);
659 up_write(&tty->termios_rwsem);
660}
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677int tty_ldisc_reinit(struct tty_struct *tty, int disc)
678{
679 struct tty_ldisc *ld;
680 int retval;
681
682 ld = tty_ldisc_get(tty, disc);
683 if (IS_ERR(ld)) {
684 BUG_ON(disc == N_TTY);
685 return PTR_ERR(ld);
686 }
687
688 if (tty->ldisc) {
689 tty_ldisc_close(tty, tty->ldisc);
690 tty_ldisc_put(tty->ldisc);
691 }
692
693
694 tty->ldisc = ld;
695 tty_set_termios_ldisc(tty, disc);
696 retval = tty_ldisc_open(tty, tty->ldisc);
697 if (retval) {
698 tty_ldisc_put(tty->ldisc);
699 tty->ldisc = NULL;
700 }
701 return retval;
702}
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719void tty_ldisc_hangup(struct tty_struct *tty, bool reinit)
720{
721 struct tty_ldisc *ld;
722
723 tty_ldisc_debug(tty, "%p: hangup\n", tty->ldisc);
724
725 ld = tty_ldisc_ref(tty);
726 if (ld != NULL) {
727 if (ld->ops->flush_buffer)
728 ld->ops->flush_buffer(tty);
729 tty_driver_flush_buffer(tty);
730 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
731 ld->ops->write_wakeup)
732 ld->ops->write_wakeup(tty);
733 if (ld->ops->hangup)
734 ld->ops->hangup(tty);
735 tty_ldisc_deref(ld);
736 }
737
738 wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT);
739 wake_up_interruptible_poll(&tty->read_wait, EPOLLIN);
740
741
742
743
744
745
746
747 tty_ldisc_lock(tty, MAX_SCHEDULE_TIMEOUT);
748
749 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
750 tty_reset_termios(tty);
751
752 if (tty->ldisc) {
753 if (reinit) {
754 if (tty_ldisc_reinit(tty, tty->termios.c_line) < 0 &&
755 tty_ldisc_reinit(tty, N_TTY) < 0)
756 WARN_ON(tty_ldisc_reinit(tty, N_NULL) < 0);
757 } else
758 tty_ldisc_kill(tty);
759 }
760 tty_ldisc_unlock(tty);
761}
762
763
764
765
766
767
768
769
770
771
772
773int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty)
774{
775 int retval = tty_ldisc_open(tty, tty->ldisc);
776 if (retval)
777 return retval;
778
779 if (o_tty) {
780 retval = tty_ldisc_open(o_tty, o_tty->ldisc);
781 if (retval) {
782 tty_ldisc_close(tty, tty->ldisc);
783 return retval;
784 }
785 }
786 return 0;
787}
788
789
790
791
792
793
794
795
796
797void tty_ldisc_release(struct tty_struct *tty)
798{
799 struct tty_struct *o_tty = tty->link;
800
801
802
803
804
805
806 tty_ldisc_lock_pair(tty, o_tty);
807 tty_ldisc_kill(tty);
808 if (o_tty)
809 tty_ldisc_kill(o_tty);
810 tty_ldisc_unlock_pair(tty, o_tty);
811
812
813
814
815 tty_ldisc_debug(tty, "released\n");
816}
817EXPORT_SYMBOL_GPL(tty_ldisc_release);
818
819
820
821
822
823
824
825
826
827void tty_ldisc_init(struct tty_struct *tty)
828{
829 struct tty_ldisc *ld = tty_ldisc_get(tty, N_TTY);
830 if (IS_ERR(ld))
831 panic("n_tty: init_tty");
832 tty->ldisc = ld;
833}
834
835
836
837
838
839
840
841
842void tty_ldisc_deinit(struct tty_struct *tty)
843{
844 if (tty->ldisc)
845 tty_ldisc_put(tty->ldisc);
846 tty->ldisc = NULL;
847}
848