From: Al Viro <v...@zeniv.linux.org.uk>

Signed-off-by: Al Viro <v...@zeniv.linux.org.uk>
---
 drivers/tty/serial/serial_core.c | 38 ++++++++++++--------------------------
 1 file changed, 12 insertions(+), 26 deletions(-)

diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 80bb56facfb6..2c8162b8ebf2 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -778,17 +778,13 @@ static int uart_get_info(struct tty_port *port, struct 
serial_struct *retinfo)
        return ret;
 }
 
-static int uart_get_info_user(struct tty_port *port,
-                        struct serial_struct __user *retinfo)
+static int uart_get_info_user(struct tty_struct *tty,
+                        struct serial_struct *ss)
 {
-       struct serial_struct tmp;
-
-       if (uart_get_info(port, &tmp) < 0)
-               return -EIO;
+       struct uart_state *state = tty->driver_data;
+       struct tty_port *port = &state->port;
 
-       if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
-               return -EFAULT;
-       return 0;
+       return uart_get_info(port, ss) < 0 ? -EIO : 0;
 }
 
 static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
@@ -990,16 +986,13 @@ static int uart_set_info(struct tty_struct *tty, struct 
tty_port *port,
        return retval;
 }
 
-static int uart_set_info_user(struct tty_struct *tty, struct uart_state *state,
-                        struct serial_struct __user *newinfo)
+static int uart_set_info_user(struct tty_struct *tty, struct serial_struct *ss)
 {
-       struct serial_struct new_serial;
+       struct uart_state *state = tty->driver_data;
        struct tty_port *port = &state->port;
        int retval;
 
-       if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
-               return -EFAULT;
-
+       down_write(&tty->termios_rwsem);
        /*
         * This semaphore protects port->count.  It is also
         * very useful to prevent opens.  Also, take the
@@ -1008,8 +1001,9 @@ static int uart_set_info_user(struct tty_struct *tty, 
struct uart_state *state,
         * under us.
         */
        mutex_lock(&port->mutex);
-       retval = uart_set_info(tty, port, state, &new_serial);
+       retval = uart_set_info(tty, port, state, ss);
        mutex_unlock(&port->mutex);
+       up_write(&tty->termios_rwsem);
        return retval;
 }
 
@@ -1325,16 +1319,6 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, 
unsigned long arg)
         * These ioctls don't rely on the hardware to be present.
         */
        switch (cmd) {
-       case TIOCGSERIAL:
-               ret = uart_get_info_user(port, uarg);
-               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);
@@ -2413,6 +2397,8 @@ static const struct tty_operations uart_ops = {
 #endif
        .tiocmget       = uart_tiocmget,
        .tiocmset       = uart_tiocmset,
+       .set_serial     = uart_set_info_user,
+       .get_serial     = uart_get_info_user,
        .get_icount     = uart_get_icount,
 #ifdef CONFIG_CONSOLE_POLL
        .poll_init      = uart_poll_init,
-- 
2.11.0

Reply via email to