X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Ftty%2Ftty_ldisc.c;h=3737f55272d2c1184463edc3714f89fb2724730e;hb=28023d2a8e9121b1b06c3b46e523c3c7a3e8b530;hp=1dbe27824220266e1dd23b71bab7f6edadae32d1;hpb=fae76e9adfa450f4c2dd5773265eb3c811a9c484;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 1dbe27824220..3737f55272d2 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -393,33 +393,21 @@ static void __lockfunc tty_ldisc_unlock_pair(struct tty_struct *tty, __tty_ldisc_unlock(tty2); } -static void __lockfunc tty_ldisc_enable_pair(struct tty_struct *tty, - struct tty_struct *tty2) -{ - clear_bit(TTY_LDISC_HALTED, &tty->flags); - if (tty2) - clear_bit(TTY_LDISC_HALTED, &tty2->flags); - - tty_ldisc_unlock_pair(tty, tty2); -} - /** * tty_ldisc_flush - flush line discipline queue * @tty: tty * - * Flush the line discipline queue (if any) for this tty. If there - * is no line discipline active this is a no-op. + * Flush the line discipline queue (if any) and the tty flip buffers + * for this tty. */ void tty_ldisc_flush(struct tty_struct *tty) { struct tty_ldisc *ld = tty_ldisc_ref(tty); - if (ld) { - if (ld->ops->flush_buffer) - ld->ops->flush_buffer(tty); + + tty_buffer_flush(tty, ld); + if (ld) tty_ldisc_deref(ld); - } - tty_buffer_flush(tty); } EXPORT_SYMBOL_GPL(tty_ldisc_flush); @@ -535,14 +523,13 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) { int retval; struct tty_ldisc *old_ldisc, *new_ldisc; - struct tty_struct *o_tty = tty->link; new_ldisc = tty_ldisc_get(tty, ldisc); if (IS_ERR(new_ldisc)) return PTR_ERR(new_ldisc); tty_lock(tty); - retval = tty_ldisc_lock_pair_timeout(tty, o_tty, 5 * HZ); + retval = tty_ldisc_lock(tty, 5 * HZ); if (retval) { tty_ldisc_put(new_ldisc); tty_unlock(tty); @@ -554,7 +541,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) */ if (tty->ldisc->ops->num == ldisc) { - tty_ldisc_enable_pair(tty, o_tty); + tty_ldisc_unlock(tty); tty_ldisc_put(new_ldisc); tty_unlock(tty); return 0; @@ -565,7 +552,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) if (test_bit(TTY_HUPPED, &tty->flags)) { /* We were raced by the hangup method. It will have stomped the ldisc data and closed the ldisc down */ - tty_ldisc_enable_pair(tty, o_tty); + tty_ldisc_unlock(tty); tty_ldisc_put(new_ldisc); tty_unlock(tty); return -EIO; @@ -585,8 +572,11 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) tty_ldisc_restore(tty, old_ldisc); } - if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) + if (tty->ldisc->ops->num != old_ldisc->ops->num && tty->ops->set_ldisc) { + down_read(&tty->termios_rwsem); tty->ops->set_ldisc(tty); + up_read(&tty->termios_rwsem); + } /* At this point we hold a reference to the new ldisc and a reference to the old ldisc, or we hold two references to @@ -599,13 +589,11 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) /* * Allow ldisc referencing to occur again */ - tty_ldisc_enable_pair(tty, o_tty); + tty_ldisc_unlock(tty); /* Restart the work queue in case no characters kick it off. Safe if already running */ schedule_work(&tty->port->buf.work); - if (o_tty) - schedule_work(&o_tty->port->buf.work); tty_unlock(tty); return retval;