diff options
author | Peter Hurley <peter@hurleysoftware.com> | 2016-04-10 02:53:22 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-04-30 18:26:55 +0200 |
commit | 807c8d81f4ec441241cafa3034c58df721fee869 (patch) | |
tree | 83402ad7f36b135d15d1aa6686ff26aa186b3dec /drivers/tty | |
parent | tty: Replace ASYNC_CTS_FLOW bit and update atomically (diff) | |
download | linux-807c8d81f4ec441241cafa3034c58df721fee869.tar.xz linux-807c8d81f4ec441241cafa3034c58df721fee869.zip |
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>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/amiserial.c | 2 | ||||
-rw-r--r-- | drivers/tty/rocket.c | 5 | ||||
-rw-r--r-- | drivers/tty/serial/crisv10.c | 8 | ||||
-rw-r--r-- | drivers/tty/serial/serial_core.c | 8 | ||||
-rw-r--r-- | drivers/tty/synclink.c | 6 | ||||
-rw-r--r-- | drivers/tty/synclink_gt.c | 6 | ||||
-rw-r--r-- | drivers/tty/synclinkmp.c | 6 | ||||
-rw-r--r-- | drivers/tty/tty_port.c | 12 |
8 files changed, 27 insertions, 26 deletions
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 92717b088959..80d61658efb0 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c @@ -1493,7 +1493,7 @@ static void rs_hangup(struct tty_struct *tty) rs_flush_buffer(tty); shutdown(tty, info); info->tport.count = 0; - info->tport.flags &= ~ASYNC_NORMAL_ACTIVE; + tty_port_set_active(&info->tport, 0); info->tport.tty = NULL; wake_up_interruptible(&info->tport.open_wait); } diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 0b802cdd70d0..eb8311b20782 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c @@ -1042,9 +1042,10 @@ static void rp_close(struct tty_struct *tty, struct file *filp) } } spin_lock_irq(&port->lock); - info->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_NORMAL_ACTIVE); + port->flags &= ~ASYNC_INITIALIZED; tty->closing = 0; spin_unlock_irq(&port->lock); + tty_port_set_active(port, 0); mutex_unlock(&port->mutex); tty_port_tty_set(port, NULL); @@ -1624,7 +1625,7 @@ static int rp_write(struct tty_struct *tty, /* Write remaining data into the port's xmit_buf */ while (1) { /* Hung up ? */ - if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags)) + if (!tty_port_active(&info->port)) goto end; c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1); c = min(c, XMIT_BUF_SIZE - info->xmit_head); diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 546990334815..92c8c628e00e 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c @@ -3648,8 +3648,8 @@ rs_close(struct tty_struct *tty, struct file * filp) schedule_timeout_interruptible(info->port.close_delay); wake_up_interruptible(&info->port.open_wait); } - info->port.flags &= ~ASYNC_NORMAL_ACTIVE; local_irq_restore(flags); + tty_port_set_active(&info->port, 0); /* port closed */ @@ -3732,7 +3732,7 @@ rs_hangup(struct tty_struct *tty) shutdown(info); info->event = 0; info->port.count = 0; - info->port.flags &= ~ASYNC_NORMAL_ACTIVE; + tty_port_set_active(&info->port, 0); info->port.tty = NULL; wake_up_interruptible(&info->port.open_wait); } @@ -3756,7 +3756,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, * then make the check up front and then exit. */ if ((filp->f_flags & O_NONBLOCK) || tty_io_error(tty)) { - info->port.flags |= ASYNC_NORMAL_ACTIVE; + tty_port_set_active(&info->port, 1); return 0; } @@ -3825,7 +3825,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, #endif if (retval) return retval; - info->port.flags |= ASYNC_NORMAL_ACTIVE; + tty_port_set_active(&info->port, 1); return 0; } diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 64a5c00d7468..2471380fb92e 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1418,12 +1418,12 @@ static void uart_close(struct tty_struct *tty, struct file *filp) uart_change_pm(state, UART_PM_STATE_OFF); spin_lock_irq(&port->lock); } + spin_unlock_irq(&port->lock); + tty_port_set_active(port, 0); /* * Wake up anyone trying to open this port. */ - clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); - spin_unlock_irq(&port->lock); wake_up_interruptible(&port->open_wait); mutex_unlock(&port->mutex); @@ -1501,13 +1501,13 @@ static void uart_hangup(struct tty_struct *tty) pr_debug("uart_hangup(%d)\n", tty->index); mutex_lock(&port->mutex); - if (port->flags & ASYNC_NORMAL_ACTIVE) { + if (tty_port_active(port)) { uart_flush_buffer(tty); uart_shutdown(tty, state); spin_lock_irqsave(&port->lock, flags); port->count = 0; - clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); spin_unlock_irqrestore(&port->lock, flags); + tty_port_set_active(port, 0); tty_port_tty_set(port, NULL); if (!uart_console(state->uart_port)) uart_change_pm(state, UART_PM_STATE_OFF); diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 0e4290183280..b55f8468cde5 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c @@ -3201,7 +3201,7 @@ static void mgsl_hangup(struct tty_struct *tty) shutdown(info); info->port.count = 0; - info->port.flags &= ~ASYNC_NORMAL_ACTIVE; + tty_port_set_active(&info->port, 0); info->port.tty = NULL; wake_up_interruptible(&info->port.open_wait); @@ -3269,7 +3269,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) { /* nonblock mode is set or port is not enabled */ - port->flags |= ASYNC_NORMAL_ACTIVE; + tty_port_set_active(port, 1); return 0; } @@ -3338,7 +3338,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, __FILE__,__LINE__, tty->driver->name, port->count ); if (!retval) - port->flags |= ASYNC_NORMAL_ACTIVE; + tty_port_set_active(port, 1); return retval; diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 5da69d30f816..c76f546697dc 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -756,9 +756,9 @@ static void hangup(struct tty_struct *tty) spin_lock_irqsave(&info->port.lock, flags); info->port.count = 0; - info->port.flags &= ~ASYNC_NORMAL_ACTIVE; info->port.tty = NULL; spin_unlock_irqrestore(&info->port.lock, flags); + tty_port_set_active(&info->port, 0); mutex_unlock(&info->port.mutex); wake_up_interruptible(&info->port.open_wait); @@ -3268,7 +3268,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) { /* nonblock mode is set or port is not enabled */ - port->flags |= ASYNC_NORMAL_ACTIVE; + tty_port_set_active(port, 1); return 0; } @@ -3325,7 +3325,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, port->blocked_open--; if (!retval) - port->flags |= ASYNC_NORMAL_ACTIVE; + tty_port_set_active(port, 1); DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval)); return retval; diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index 7a21491d0c0d..95eddc4d9eb8 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c @@ -849,9 +849,9 @@ static void hangup(struct tty_struct *tty) spin_lock_irqsave(&info->port.lock, flags); info->port.count = 0; - info->port.flags &= ~ASYNC_NORMAL_ACTIVE; info->port.tty = NULL; spin_unlock_irqrestore(&info->port.lock, flags); + tty_port_set_active(&info->port, 1); mutex_unlock(&info->port.mutex); wake_up_interruptible(&info->port.open_wait); @@ -3285,7 +3285,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) { /* nonblock mode is set or port is not enabled */ /* just verify that callout device is not active */ - port->flags |= ASYNC_NORMAL_ACTIVE; + tty_port_set_active(port, 1); return 0; } @@ -3352,7 +3352,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, __FILE__,__LINE__, tty->driver->name, port->count ); if (!retval) - port->flags |= ASYNC_NORMAL_ACTIVE; + tty_port_set_active(port, 1); return retval; } diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index 9127c54b803e..130c8cf520cb 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c @@ -236,12 +236,12 @@ void tty_port_hangup(struct tty_port *port) spin_lock_irqsave(&port->lock, flags); port->count = 0; - port->flags &= ~ASYNC_NORMAL_ACTIVE; tty = port->tty; if (tty) set_bit(TTY_IO_ERROR, &tty->flags); port->tty = NULL; spin_unlock_irqrestore(&port->lock, flags); + tty_port_set_active(port, 0); tty_port_shutdown(port, tty); tty_kref_put(tty); wake_up_interruptible(&port->open_wait); @@ -365,14 +365,14 @@ int tty_port_block_til_ready(struct tty_port *port, /* if non-blocking mode is set we can pass directly to open unless the port has just hung up or is in another error state */ if (tty_io_error(tty)) { - port->flags |= ASYNC_NORMAL_ACTIVE; + tty_port_set_active(port, 1); return 0; } if (filp->f_flags & O_NONBLOCK) { /* Indicate we are open */ if (C_BAUD(tty)) tty_port_raise_dtr_rts(port); - port->flags |= ASYNC_NORMAL_ACTIVE; + tty_port_set_active(port, 1); return 0; } @@ -430,9 +430,9 @@ int tty_port_block_til_ready(struct tty_port *port, if (!tty_hung_up_p(filp)) port->count++; port->blocked_open--; - if (retval == 0) - port->flags |= ASYNC_NORMAL_ACTIVE; spin_unlock_irqrestore(&port->lock, flags); + if (retval == 0) + tty_port_set_active(port, 1); return retval; } EXPORT_SYMBOL(tty_port_block_til_ready); @@ -514,8 +514,8 @@ void tty_port_close_end(struct tty_port *port, struct tty_struct *tty) spin_lock_irqsave(&port->lock, flags); wake_up_interruptible(&port->open_wait); } - port->flags &= ~ASYNC_NORMAL_ACTIVE; spin_unlock_irqrestore(&port->lock, flags); + tty_port_set_active(port, 0); } EXPORT_SYMBOL(tty_port_close_end); |