]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/serial/serial_core.c
[SERIAL] 8250: limit range of runtime ports
[karo-tx-linux.git] / drivers / serial / serial_core.c
index 2ca620900bcc24cf9b6f18850853597ddbbdaab2..95fb4939c675f8119a2b630c6e23a380fc7a9d44 100644 (file)
@@ -332,7 +332,7 @@ uart_get_baud_rate(struct uart_port *port, struct termios *termios,
                   struct termios *old, unsigned int min, unsigned int max)
 {
        unsigned int try, baud, altbaud = 38400;
-       unsigned int flags = port->flags & UPF_SPD_MASK;
+       upf_t flags = port->flags & UPF_SPD_MASK;
 
        if (flags == UPF_SPD_HI)
                altbaud = 57600;
@@ -615,8 +615,9 @@ static int uart_set_info(struct uart_state *state,
        struct serial_struct new_serial;
        struct uart_port *port = state->port;
        unsigned long new_port;
-       unsigned int change_irq, change_port, old_flags, closing_wait;
+       unsigned int change_irq, change_port, closing_wait;
        unsigned int old_custom_divisor, close_delay;
+       upf_t old_flags, new_flags;
        int retval = 0;
 
        if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
@@ -638,7 +639,7 @@ static int uart_set_info(struct uart_state *state,
         * module insertion/removal doesn't change anything
         * under us.
         */
-       down(&state->sem);
+       mutex_lock(&state->mutex);
 
        change_irq  = new_serial.irq != port->irq;
 
@@ -655,6 +656,7 @@ static int uart_set_info(struct uart_state *state,
                      new_serial.type != port->type;
 
        old_flags = port->flags;
+       new_flags = new_serial.flags;
        old_custom_divisor = port->custom_divisor;
 
        if (!capable(CAP_SYS_ADMIN)) {
@@ -664,10 +666,10 @@ static int uart_set_info(struct uart_state *state,
                    (close_delay != state->close_delay) ||
                    (closing_wait != state->closing_wait) ||
                    (new_serial.xmit_fifo_size != port->fifosize) ||
-                   (((new_serial.flags ^ old_flags) & ~UPF_USR_MASK) != 0))
+                   (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0))
                        goto exit;
                port->flags = ((port->flags & ~UPF_USR_MASK) |
-                              (new_serial.flags & UPF_USR_MASK));
+                              (new_flags & UPF_USR_MASK));
                port->custom_divisor = new_serial.custom_divisor;
                goto check_and_exit;
        }
@@ -764,7 +766,7 @@ static int uart_set_info(struct uart_state *state,
        port->irq              = new_serial.irq;
        port->uartclk          = new_serial.baud_base * 16;
        port->flags            = (port->flags & ~UPF_CHANGE_MASK) |
-                                (new_serial.flags & UPF_CHANGE_MASK);
+                                (new_flags & UPF_CHANGE_MASK);
        port->custom_divisor   = new_serial.custom_divisor;
        state->close_delay     = close_delay;
        state->closing_wait    = closing_wait;
@@ -797,7 +799,7 @@ static int uart_set_info(struct uart_state *state,
        } else
                retval = uart_startup(state, 1);
  exit:
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
        return retval;
 }
 
@@ -834,7 +836,7 @@ static int uart_tiocmget(struct tty_struct *tty, struct file *file)
        struct uart_port *port = state->port;
        int result = -EIO;
 
-       down(&state->sem);
+       mutex_lock(&state->mutex);
        if ((!file || !tty_hung_up_p(file)) &&
            !(tty->flags & (1 << TTY_IO_ERROR))) {
                result = port->mctrl;
@@ -843,7 +845,7 @@ static int uart_tiocmget(struct tty_struct *tty, struct file *file)
                result |= port->ops->get_mctrl(port);
                spin_unlock_irq(&port->lock);
        }
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
 
        return result;
 }
@@ -856,13 +858,13 @@ uart_tiocmset(struct tty_struct *tty, struct file *file,
        struct uart_port *port = state->port;
        int ret = -EIO;
 
-       down(&state->sem);
+       mutex_lock(&state->mutex);
        if ((!file || !tty_hung_up_p(file)) &&
            !(tty->flags & (1 << TTY_IO_ERROR))) {
                uart_update_mctrl(port, set, clear);
                ret = 0;
        }
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
        return ret;
 }
 
@@ -873,12 +875,12 @@ static void uart_break_ctl(struct tty_struct *tty, int break_state)
 
        BUG_ON(!kernel_locked());
 
-       down(&state->sem);
+       mutex_lock(&state->mutex);
 
        if (port->type != PORT_UNKNOWN)
                port->ops->break_ctl(port, break_state);
 
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
 }
 
 static int uart_do_autoconfig(struct uart_state *state)
@@ -894,7 +896,7 @@ static int uart_do_autoconfig(struct uart_state *state)
         * changing, and hence any extra opens of the port while
         * we're auto-configuring.
         */
-       if (down_interruptible(&state->sem))
+       if (mutex_lock_interruptible(&state->mutex))
                return -ERESTARTSYS;
 
        ret = -EBUSY;
@@ -920,7 +922,7 @@ static int uart_do_autoconfig(struct uart_state *state)
 
                ret = uart_startup(state, 1);
        }
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
        return ret;
 }
 
@@ -1074,7 +1076,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
        if (ret != -ENOIOCTLCMD)
                goto out;
 
-       down(&state->sem);
+       mutex_lock(&state->mutex);
 
        if (tty_hung_up_p(filp)) {
                ret = -EIO;
@@ -1098,7 +1100,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
        }
        }
  out_up:
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
  out:
        return ret;
 }
@@ -1186,7 +1188,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 
        DPRINTK("uart_close(%d) called\n", port->line);
 
-       down(&state->sem);
+       mutex_lock(&state->mutex);
 
        if (tty_hung_up_p(filp))
                goto done;
@@ -1260,7 +1262,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
        wake_up_interruptible(&state->info->open_wait);
 
  done:
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
 }
 
 static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
@@ -1334,7 +1336,7 @@ static void uart_hangup(struct tty_struct *tty)
        BUG_ON(!kernel_locked());
        DPRINTK("uart_hangup(%d)\n", state->port->line);
 
-       down(&state->sem);
+       mutex_lock(&state->mutex);
        if (state->info && state->info->flags & UIF_NORMAL_ACTIVE) {
                uart_flush_buffer(tty);
                uart_shutdown(state);
@@ -1344,7 +1346,7 @@ static void uart_hangup(struct tty_struct *tty)
                wake_up_interruptible(&state->info->open_wait);
                wake_up_interruptible(&state->info->delta_msr_wait);
        }
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
 }
 
 /*
@@ -1447,9 +1449,9 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
                if (mctrl & TIOCM_CAR)
                        break;
 
-               up(&state->sem);
+               mutex_unlock(&state->mutex);
                schedule();
-               down(&state->sem);
+               mutex_lock(&state->mutex);
 
                if (signal_pending(current))
                        break;
@@ -1475,7 +1477,7 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
 
        mutex_lock(&port_mutex);
        state = drv->state + line;
-       if (down_interruptible(&state->sem)) {
+       if (mutex_lock_interruptible(&state->mutex)) {
                state = ERR_PTR(-ERESTARTSYS);
                goto out;
        }
@@ -1483,7 +1485,7 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
        state->count++;
        if (!state->port) {
                state->count--;
-               up(&state->sem);
+               mutex_unlock(&state->mutex);
                state = ERR_PTR(-ENXIO);
                goto out;
        }
@@ -1504,7 +1506,7 @@ static struct uart_state *uart_get(struct uart_driver *drv, int line)
                                     (unsigned long)state);
                } else {
                        state->count--;
-                       up(&state->sem);
+                       mutex_unlock(&state->mutex);
                        state = ERR_PTR(-ENOMEM);
                }
        }
@@ -1571,7 +1573,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
        if (tty_hung_up_p(filp)) {
                retval = -EAGAIN;
                state->count--;
-               up(&state->sem);
+               mutex_unlock(&state->mutex);
                goto fail;
        }
 
@@ -1591,7 +1593,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
         */
        if (retval == 0)
                retval = uart_block_til_ready(filp, state);
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
 
        /*
         * If this is the first open to succeed, adjust things to suit.
@@ -1867,10 +1869,10 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
 {
        struct uart_state *state = drv->state + port->line;
 
-       down(&state->sem);
+       mutex_lock(&state->mutex);
 
        if (state->info && state->info->flags & UIF_INITIALIZED) {
-               struct uart_ops *ops = port->ops;
+               const struct uart_ops *ops = port->ops;
 
                spin_lock_irq(&port->lock);
                ops->stop_tx(port);
@@ -1896,7 +1898,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
 
        uart_change_pm(state, 3);
 
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
 
        return 0;
 }
@@ -1905,7 +1907,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
 {
        struct uart_state *state = drv->state + port->line;
 
-       down(&state->sem);
+       mutex_lock(&state->mutex);
 
        uart_change_pm(state, 0);
 
@@ -1932,7 +1934,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
        }
 
        if (state->info && state->info->flags & UIF_INITIALIZED) {
-               struct uart_ops *ops = port->ops;
+               const struct uart_ops *ops = port->ops;
                int ret;
 
                ops->set_mctrl(port, 0);
@@ -1954,7 +1956,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
                }
        }
 
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
 
        return 0;
 }
@@ -2049,7 +2051,7 @@ uart_unconfigure_port(struct uart_driver *drv, struct uart_state *state)
        if (info && info->tty)
                tty_vhangup(info->tty);
 
-       down(&state->sem);
+       mutex_lock(&state->mutex);
 
        state->info = NULL;
 
@@ -2072,7 +2074,7 @@ uart_unconfigure_port(struct uart_driver *drv, struct uart_state *state)
                kfree(info);
        }
 
-       up(&state->sem);
+       mutex_unlock(&state->mutex);
 }
 
 static struct tty_operations uart_ops = {
@@ -2161,7 +2163,7 @@ int uart_register_driver(struct uart_driver *drv)
                state->close_delay     = 500;   /* .5 seconds */
                state->closing_wait    = 30000; /* 30 seconds */
 
-               init_MUTEX(&state->sem);
+               mutex_init(&state->mutex);
        }
 
        retval = tty_register_driver(normal);
@@ -2235,7 +2237,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
         * If this port is a console, then the spinlock is already
         * initialised.
         */
-       if (!uart_console(port))
+       if (!(uart_console(port) && (port->cons->flags & CON_ENABLED)))
                spin_lock_init(&port->lock);
 
        uart_configure_port(drv, state, port);