aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_ldisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/tty_ldisc.c')
-rw-r--r--drivers/tty/tty_ldisc.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 24b95db75d8..173a9000a6c 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -28,7 +28,6 @@
28 28
29static DEFINE_SPINLOCK(tty_ldisc_lock); 29static DEFINE_SPINLOCK(tty_ldisc_lock);
30static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); 30static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
31static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_idle);
32/* Line disc dispatch table */ 31/* Line disc dispatch table */
33static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS]; 32static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
34 33
@@ -65,7 +64,7 @@ static void put_ldisc(struct tty_ldisc *ld)
65 return; 64 return;
66 } 65 }
67 local_irq_restore(flags); 66 local_irq_restore(flags);
68 wake_up(&tty_ldisc_idle); 67 wake_up(&ld->wq_idle);
69} 68}
70 69
71/** 70/**
@@ -200,6 +199,8 @@ static struct tty_ldisc *tty_ldisc_get(int disc)
200 199
201 ld->ops = ldops; 200 ld->ops = ldops;
202 atomic_set(&ld->users, 1); 201 atomic_set(&ld->users, 1);
202 init_waitqueue_head(&ld->wq_idle);
203
203 return ld; 204 return ld;
204} 205}
205 206
@@ -538,7 +539,7 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
538static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) 539static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
539{ 540{
540 long ret; 541 long ret;
541 ret = wait_event_timeout(tty_ldisc_idle, 542 ret = wait_event_timeout(tty->ldisc->wq_idle,
542 atomic_read(&tty->ldisc->users) == 1, timeout); 543 atomic_read(&tty->ldisc->users) == 1, timeout);
543 return ret > 0 ? 0 : -EBUSY; 544 return ret > 0 ? 0 : -EBUSY;
544} 545}
@@ -567,7 +568,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
567 if (IS_ERR(new_ldisc)) 568 if (IS_ERR(new_ldisc))
568 return PTR_ERR(new_ldisc); 569 return PTR_ERR(new_ldisc);
569 570
570 tty_lock(); 571 tty_lock(tty);
571 /* 572 /*
572 * We need to look at the tty locking here for pty/tty pairs 573 * We need to look at the tty locking here for pty/tty pairs
573 * when both sides try to change in parallel. 574 * when both sides try to change in parallel.
@@ -581,12 +582,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
581 */ 582 */
582 583
583 if (tty->ldisc->ops->num == ldisc) { 584 if (tty->ldisc->ops->num == ldisc) {
584 tty_unlock(); 585 tty_unlock(tty);
585 tty_ldisc_put(new_ldisc); 586 tty_ldisc_put(new_ldisc);
586 return 0; 587 return 0;
587 } 588 }
588 589
589 tty_unlock(); 590 tty_unlock(tty);
590 /* 591 /*
591 * Problem: What do we do if this blocks ? 592 * Problem: What do we do if this blocks ?
592 * We could deadlock here 593 * We could deadlock here
@@ -594,7 +595,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
594 595
595 tty_wait_until_sent(tty, 0); 596 tty_wait_until_sent(tty, 0);
596 597
597 tty_lock(); 598 tty_lock(tty);
598 mutex_lock(&tty->ldisc_mutex); 599 mutex_lock(&tty->ldisc_mutex);
599 600
600 /* 601 /*
@@ -604,10 +605,10 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
604 605
605 while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { 606 while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) {
606 mutex_unlock(&tty->ldisc_mutex); 607 mutex_unlock(&tty->ldisc_mutex);
607 tty_unlock(); 608 tty_unlock(tty);
608 wait_event(tty_ldisc_wait, 609 wait_event(tty_ldisc_wait,
609 test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); 610 test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0);
610 tty_lock(); 611 tty_lock(tty);
611 mutex_lock(&tty->ldisc_mutex); 612 mutex_lock(&tty->ldisc_mutex);
612 } 613 }
613 614
@@ -622,7 +623,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
622 623
623 o_ldisc = tty->ldisc; 624 o_ldisc = tty->ldisc;
624 625
625 tty_unlock(); 626 tty_unlock(tty);
626 /* 627 /*
627 * Make sure we don't change while someone holds a 628 * Make sure we don't change while someone holds a
628 * reference to the line discipline. The TTY_LDISC bit 629 * reference to the line discipline. The TTY_LDISC bit
@@ -649,7 +650,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
649 650
650 retval = tty_ldisc_wait_idle(tty, 5 * HZ); 651 retval = tty_ldisc_wait_idle(tty, 5 * HZ);
651 652
652 tty_lock(); 653 tty_lock(tty);
653 mutex_lock(&tty->ldisc_mutex); 654 mutex_lock(&tty->ldisc_mutex);
654 655
655 /* handle wait idle failure locked */ 656 /* handle wait idle failure locked */
@@ -664,7 +665,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
664 clear_bit(TTY_LDISC_CHANGING, &tty->flags); 665 clear_bit(TTY_LDISC_CHANGING, &tty->flags);
665 mutex_unlock(&tty->ldisc_mutex); 666 mutex_unlock(&tty->ldisc_mutex);
666 tty_ldisc_put(new_ldisc); 667 tty_ldisc_put(new_ldisc);
667 tty_unlock(); 668 tty_unlock(tty);
668 return -EIO; 669 return -EIO;
669 } 670 }
670 671
@@ -707,7 +708,7 @@ enable:
707 if (o_work) 708 if (o_work)
708 schedule_work(&o_tty->buf.work); 709 schedule_work(&o_tty->buf.work);
709 mutex_unlock(&tty->ldisc_mutex); 710 mutex_unlock(&tty->ldisc_mutex);
710 tty_unlock(); 711 tty_unlock(tty);
711 return retval; 712 return retval;
712} 713}
713 714
@@ -815,11 +816,11 @@ void tty_ldisc_hangup(struct tty_struct *tty)
815 * need to wait for another function taking the BTM 816 * need to wait for another function taking the BTM
816 */ 817 */
817 clear_bit(TTY_LDISC, &tty->flags); 818 clear_bit(TTY_LDISC, &tty->flags);
818 tty_unlock(); 819 tty_unlock(tty);
819 cancel_work_sync(&tty->buf.work); 820 cancel_work_sync(&tty->buf.work);
820 mutex_unlock(&tty->ldisc_mutex); 821 mutex_unlock(&tty->ldisc_mutex);
821retry: 822retry:
822 tty_lock(); 823 tty_lock(tty);
823 mutex_lock(&tty->ldisc_mutex); 824 mutex_lock(&tty->ldisc_mutex);
824 825
825 /* At this point we have a closed ldisc and we want to 826 /* At this point we have a closed ldisc and we want to
@@ -830,7 +831,7 @@ retry:
830 if (atomic_read(&tty->ldisc->users) != 1) { 831 if (atomic_read(&tty->ldisc->users) != 1) {
831 char cur_n[TASK_COMM_LEN], tty_n[64]; 832 char cur_n[TASK_COMM_LEN], tty_n[64];
832 long timeout = 3 * HZ; 833 long timeout = 3 * HZ;
833 tty_unlock(); 834 tty_unlock(tty);
834 835
835 while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { 836 while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
836 timeout = MAX_SCHEDULE_TIMEOUT; 837 timeout = MAX_SCHEDULE_TIMEOUT;
@@ -911,10 +912,10 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
911 * race with the set_ldisc code path. 912 * race with the set_ldisc code path.
912 */ 913 */
913 914
914 tty_unlock(); 915 tty_unlock(tty);
915 tty_ldisc_halt(tty); 916 tty_ldisc_halt(tty);
916 tty_ldisc_flush_works(tty); 917 tty_ldisc_flush_works(tty);
917 tty_lock(); 918 tty_lock(tty);
918 919
919 mutex_lock(&tty->ldisc_mutex); 920 mutex_lock(&tty->ldisc_mutex);
920 /* 921 /*