vserver 1.9.3
[linux-2.6.git] / drivers / serial / serial_core.c
index 66bb3cf..1ac6c9d 100644 (file)
@@ -107,15 +107,7 @@ static void uart_start(struct tty_struct *tty)
 static void uart_tasklet_action(unsigned long data)
 {
        struct uart_state *state = (struct uart_state *)data;
-       struct tty_struct *tty;
-
-       tty = state->info->tty;
-       if (tty) {
-               if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                   tty->ldisc.write_wakeup)
-                       tty->ldisc.write_wakeup(tty);
-               wake_up_interruptible(&tty->write_wait);
-       }
+       tty_wakeup(state->info->tty);
 }
 
 static inline void
@@ -403,7 +395,7 @@ uart_get_divisor(struct uart_port *port, unsigned int baud)
        if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
                quot = port->custom_divisor;
        else
-               quot = port->uartclk / (16 * baud);
+               quot = (port->uartclk + (8 * baud)) / (16 * baud);
 
        return quot;
 }
@@ -460,7 +452,7 @@ __uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c)
 
 static inline int
 __uart_user_write(struct uart_port *port, struct circ_buf *circ,
-                 const unsigned char *buf, int count)
+                 const unsigned char __user *buf, int count)
 {
        unsigned long flags;
        int c, ret = 0;
@@ -546,9 +538,11 @@ uart_write(struct tty_struct *tty, int from_user, const unsigned char * buf,
                return 0;
 
        if (from_user)
-               ret = __uart_user_write(state->port, &state->info->xmit, buf, count);
+               ret = __uart_user_write(state->port, &state->info->xmit,
+                               (const unsigned char __user *)buf, count);
        else
-               ret = __uart_kern_write(state->port, &state->info->xmit, buf, count);
+               ret = __uart_kern_write(state->port, &state->info->xmit,
+                                       buf, count);
 
        uart_start(tty);
        return ret;
@@ -579,10 +573,7 @@ static void uart_flush_buffer(struct tty_struct *tty)
        spin_lock_irqsave(&port->lock, flags);
        uart_circ_clear(&state->info->xmit);
        spin_unlock_irqrestore(&port->lock, flags);
-       wake_up_interruptible(&tty->write_wait);
-       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-           tty->ldisc.write_wakeup)
-               (tty->ldisc.write_wakeup)(tty);
+       tty_wakeup(tty);
 }
 
 /*
@@ -634,7 +625,8 @@ static void uart_unthrottle(struct tty_struct *tty)
                uart_set_mctrl(port, TIOCM_RTS);
 }
 
-static int uart_get_info(struct uart_state *state, struct serial_struct *retinfo)
+static int uart_get_info(struct uart_state *state,
+                        struct serial_struct __user *retinfo)
 {
        struct uart_port *port = state->port;
        struct serial_struct tmp;
@@ -662,8 +654,8 @@ static int uart_get_info(struct uart_state *state, struct serial_struct *retinfo
        return 0;
 }
 
-static int
-uart_set_info(struct uart_state *state, struct serial_struct *newinfo)
+static int uart_set_info(struct uart_state *state,
+                        struct serial_struct __user *newinfo)
 {
        struct serial_struct new_serial;
        struct uart_port *port = state->port;
@@ -856,7 +848,8 @@ uart_set_info(struct uart_state *state, struct serial_struct *newinfo)
  * uart_get_lsr_info - get line status register info.
  * Note: uart_ioctl protects us against hangups.
  */
-static int uart_get_lsr_info(struct uart_state *state, unsigned int *value)
+static int uart_get_lsr_info(struct uart_state *state,
+                            unsigned int __user *value)
 {
        struct uart_port *port = state->port;
        unsigned int result;
@@ -1035,8 +1028,8 @@ uart_wait_modem_status(struct uart_state *state, unsigned long arg)
  * NB: both 1->0 and 0->1 transitions are counted except for
  *     RI where only 0->1 is counted.
  */
-static int
-uart_get_count(struct uart_state *state, struct serial_icounter_struct *icnt)
+static int uart_get_count(struct uart_state *state,
+                         struct serial_icounter_struct __user *icnt)
 {
        struct serial_icounter_struct icount;
        struct uart_icount cnow;
@@ -1069,6 +1062,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
           unsigned long arg)
 {
        struct uart_state *state = tty->driver_data;
+       void __user *uarg = (void __user *)arg;
        int ret = -ENOIOCTLCMD;
 
        BUG_ON(!kernel_locked());
@@ -1078,11 +1072,11 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
         */
        switch (cmd) {
        case TIOCGSERIAL:
-               ret = uart_get_info(state, (struct serial_struct *)arg);
+               ret = uart_get_info(state, uarg);
                break;
 
        case TIOCSSERIAL:
-               ret = uart_set_info(state, (struct serial_struct *)arg);
+               ret = uart_set_info(state, uarg);
                break;
 
        case TIOCSERCONFIG:
@@ -1112,7 +1106,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
                break;
 
        case TIOCGICOUNT:
-               ret = uart_get_count(state, (struct serial_icounter_struct *)arg);
+               ret = uart_get_count(state, uarg);
                break;
        }
 
@@ -1132,7 +1126,7 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
         */
        switch (cmd) {
        case TIOCSERGETLSR: /* Get line status register */
-               ret = uart_get_lsr_info(state, (unsigned int *)arg);
+               ret = uart_get_lsr_info(state, uarg);
                break;
 
        default: {
@@ -1211,7 +1205,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 {
        struct uart_state *state = tty->driver_data;
        struct uart_port *port;
-
+       
        BUG_ON(!kernel_locked());
 
        if (!state || !state->port)
@@ -1234,12 +1228,12 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
                 * one, we've got real problems, since it means the
                 * serial port won't be shutdown.
                 */
-               printk("uart_close: bad serial port count; tty->count is 1, "
+               printk(KERN_ERR "uart_close: bad serial port count; tty->count is 1, "
                       "state->count is %d\n", state->count);
                state->count = 1;
        }
        if (--state->count < 0) {
-               printk("rs_close: bad serial port count for %s: %d\n",
+               printk(KERN_ERR "uart_close: bad serial port count for %s: %d\n",
                       tty->name, state->count);
                state->count = 0;
        }
@@ -1275,8 +1269,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
 
        uart_shutdown(state);
        uart_flush_buffer(tty);
-       if (tty->ldisc.flush_buffer)
-               tty->ldisc.flush_buffer(tty);
+
+       tty_ldisc_flush(tty);   
+       
        tty->closing = 0;
        state->info->tty = NULL;
 
@@ -1918,7 +1913,7 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
         * Disable the console device before suspending.
         */
        if (uart_console(port))
-               port->cons->flags &= ~CON_ENABLED;
+               console_stop(port->cons);
 
        uart_change_pm(state, 3);
 
@@ -1940,7 +1935,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
         */
        if (uart_console(port)) {
                uart_change_speed(state, NULL);
-               port->cons->flags |= CON_ENABLED;
+               console_start(port->cons);
        }
 
        if (state->info && state->info->flags & UIF_INITIALIZED) {
@@ -1973,6 +1968,7 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port)
                printk("I/O 0x%x offset 0x%x", port->iobase, port->hub6);
                break;
        case UPIO_MEM:
+       case UPIO_MEM32:
                printk("MMIO 0x%lx", port->mapbase);
                break;
        }