|
@@ -196,13 +196,20 @@ void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty)
|
|
|
}
|
|
|
EXPORT_SYMBOL(tty_port_tty_set);
|
|
|
|
|
|
-static void tty_port_shutdown(struct tty_port *port)
|
|
|
+static void tty_port_shutdown(struct tty_port *port, struct tty_struct *tty)
|
|
|
{
|
|
|
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 && C_HUPCL(tty))
|
|
|
+ tty_port_lower_dtr_rts(port);
|
|
|
+
|
|
|
if (port->ops->shutdown)
|
|
|
port->ops->shutdown(port);
|
|
|
}
|
|
@@ -220,18 +227,19 @@ out:
|
|
|
|
|
|
void tty_port_hangup(struct tty_port *port)
|
|
|
{
|
|
|
+ struct tty_struct *tty;
|
|
|
unsigned long flags;
|
|
|
|
|
|
spin_lock_irqsave(&port->lock, flags);
|
|
|
port->count = 0;
|
|
|
port->flags &= ~ASYNC_NORMAL_ACTIVE;
|
|
|
- if (port->tty) {
|
|
|
- set_bit(TTY_IO_ERROR, &port->tty->flags);
|
|
|
- tty_kref_put(port->tty);
|
|
|
- }
|
|
|
+ tty = port->tty;
|
|
|
+ if (tty)
|
|
|
+ set_bit(TTY_IO_ERROR, &tty->flags);
|
|
|
port->tty = NULL;
|
|
|
spin_unlock_irqrestore(&port->lock, flags);
|
|
|
- tty_port_shutdown(port);
|
|
|
+ tty_port_shutdown(port, tty);
|
|
|
+ tty_kref_put(tty);
|
|
|
wake_up_interruptible(&port->open_wait);
|
|
|
wake_up_interruptible(&port->delta_msr_wait);
|
|
|
}
|
|
@@ -485,11 +493,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 */
|
|
@@ -524,7 +527,7 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty,
|
|
|
{
|
|
|
if (tty_port_close_start(port, tty, filp) == 0)
|
|
|
return;
|
|
|
- tty_port_shutdown(port);
|
|
|
+ tty_port_shutdown(port, tty);
|
|
|
set_bit(TTY_IO_ERROR, &tty->flags);
|
|
|
tty_port_close_end(port, tty);
|
|
|
tty_port_tty_set(port, NULL);
|