diff --git a/Documentation/serial/driver b/Documentation/serial/driver index ba64e4b892e913cb4d1ff4cc2741d9f6f422c633..c415b0ef449378db4698ca9552c54bdfb387a9d0 100644 --- a/Documentation/serial/driver +++ b/Documentation/serial/driver @@ -59,7 +59,9 @@ The core driver uses the info->tmpbuf_sem lock to prevent multi-threaded access to the info->tmpbuf bouncebuffer used for port writes. The port_sem semaphore is used to protect against ports being added/ -removed or reconfigured at inappropriate times. +removed or reconfigured at inappropriate times. Since v2.6.27, this +semaphore has been the 'mutex' member of the tty_port struct, and +commonly referred to as the port mutex (or port->mutex). uart_ops @@ -248,7 +250,7 @@ hardware. Other flags may be used (eg, xon/xoff characters) if your hardware supports hardware "soft" flow control. - Locking: none. + Locking: caller holds port->mutex Interrupts: caller dependent. This call must not sleep diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 9d142972ee2d5649219b387c594cbb796221a7e6..e31d56159aee9441e5b68a259dad939a01f66aeb 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -436,7 +436,7 @@ uart_get_divisor(struct uart_port *port, unsigned int baud) EXPORT_SYMBOL(uart_get_divisor); -/* FIXME: Consistent locking policy */ +/* Caller holds port mutex */ static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, struct ktermios *old_termios) { @@ -1173,11 +1173,15 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, break; case TIOCSSERIAL: + down_write(&tty->termios_rwsem); ret = uart_set_info_user(tty, state, uarg); + up_write(&tty->termios_rwsem); break; case TIOCSERCONFIG: + down_write(&tty->termios_rwsem); ret = uart_do_autoconfig(tty, state); + up_write(&tty->termios_rwsem); break; case TIOCSERGWILD: /* obsolete */ @@ -1278,7 +1282,9 @@ static void uart_set_termios(struct tty_struct *tty, return; } + mutex_lock(&state->port.mutex); uart_change_speed(tty, state, old_termios); + mutex_unlock(&state->port.mutex); /* reload cflag from termios; port driver may have overriden flags */ cflag = tty->termios.c_cflag;