Move HUPCL handling to port shutdown so that DTR/RTS is dropped also on hang up. Currently a hung up port will return immediately from tty_port_close_start leaving DTR/RTS unchanged. --- v2: fix tty refcounting in shutdown drivers/tty/tty_port.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 57a061e..506f579 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -198,15 +198,25 @@ EXPORT_SYMBOL(tty_port_tty_set); static void tty_port_shutdown(struct tty_port *port) { + struct tty_struct *tty = tty_port_tty_get(port); + mutex_lock(&port->mutex); if (port->console) goto out; if (test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) { + /* + * Drop DTR/RTS if HUPCL is set. This causes any attached + * modem to hang up the line. + */ + if (!tty || tty->termios.c_cflag & HUPCL) + tty_port_lower_dtr_rts(port); + if (port->ops->shutdown) port->ops->shutdown(port); } out: + tty_kref_put(tty); mutex_unlock(&port->mutex); } @@ -225,15 +235,13 @@ void tty_port_hangup(struct tty_port *port) spin_lock_irqsave(&port->lock, flags); port->count = 0; port->flags &= ~ASYNC_NORMAL_ACTIVE; - if (port->tty) { + if (port->tty) set_bit(TTY_IO_ERROR, &port->tty->flags); - tty_kref_put(port->tty); - } - port->tty = NULL; spin_unlock_irqrestore(&port->lock, flags); + tty_port_shutdown(port); + tty_port_tty_set(port, NULL); wake_up_interruptible(&port->open_wait); wake_up_interruptible(&port->delta_msr_wait); - tty_port_shutdown(port); } EXPORT_SYMBOL(tty_port_hangup); @@ -452,11 +460,6 @@ int tty_port_close_start(struct tty_port *port, /* Flush the ldisc buffering */ tty_ldisc_flush(tty); - /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to - hang up the line */ - if (tty->termios.c_cflag & HUPCL) - tty_port_lower_dtr_rts(port); - /* Don't call port->drop for the last reference. Callers will want to drop the last active reference in ->shutdown() or the tty shutdown path */ -- 1.8.1.1 -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html