tty: Replace ASYNC_NORMAL_ACTIVE bit and update atomically
Replace ASYNC_NORMAL_ACTIVE bit in the tty_port::flags field with
TTY_PORT_ACTIVE bit in the tty_port::iflags field. Introduce helpers
tty_port_set_active() and tty_port_active() to abstract atomic bit ops.
Extract state changes from port lock sections, as this usage is
broken and confused; the state transitions are protected by the
tty lock (which mutually excludes parallel open/close/hangup),
and no user tests the active state while holding the port lock.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index 840b82f..681fe0b 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -281,7 +281,7 @@
* then make the check up front and then exit.
*/
if (tty_io_error(tty)) {
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ tty_port_set_active(port, 1);
return 0;
}
@@ -289,7 +289,7 @@
/* nonblock mode is set */
if (C_BAUD(tty))
tty_port_raise_dtr_rts(port);
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ tty_port_set_active(port, 1);
pr_debug("%s(), O_NONBLOCK requested!\n", __func__);
return 0;
}
@@ -365,7 +365,7 @@
__FILE__, __LINE__, tty->driver->name, port->count);
if (!retval)
- port->flags |= ASYNC_NORMAL_ACTIVE;
+ tty_port_set_active(port, 1);
return retval;
}
@@ -925,7 +925,6 @@
ircomm_tty_shutdown(self);
spin_lock_irqsave(&port->lock, flags);
- port->flags &= ~ASYNC_NORMAL_ACTIVE;
if (port->tty) {
set_bit(TTY_IO_ERROR, &port->tty->flags);
tty_kref_put(port->tty);
@@ -933,6 +932,7 @@
port->tty = NULL;
port->count = 0;
spin_unlock_irqrestore(&port->lock, flags);
+ tty_port_set_active(port, 0);
wake_up_interruptible(&port->open_wait);
}
@@ -1267,7 +1267,7 @@
seq_printf(m, "%cASYNC_LOW_LATENCY", sep);
sep = '|';
}
- if (self->port.flags & ASYNC_NORMAL_ACTIVE) {
+ if (tty_port_active(&self->port)) {
seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep);
sep = '|';
}