This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / char / vt.c
index 8de27fe..cb20edd 100644 (file)
 #include <linux/bootmem.h>
 #include <linux/pm.h>
 #include <linux/font.h>
-#include <linux/bitops.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/bitops.h>
 
 #include "console_macros.h"
 
@@ -1894,7 +1894,8 @@ char con_buf[CON_BUF_SIZE];
 DECLARE_MUTEX(con_buf_sem);
 
 /* acquires console_sem */
-static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
+static int do_con_write(struct tty_struct *tty, int from_user,
+                       const unsigned char *buf, int count)
 {
 #ifdef VT_BUF_VRAM_ONLY
 #define FLUSH do { } while(0);
@@ -1942,6 +1943,22 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
        orig_buf = buf;
        orig_count = count;
 
+       if (from_user) {
+
+               down(&con_buf_sem);
+
+again:
+               if (count > CON_BUF_SIZE)
+                       count = CON_BUF_SIZE;
+               console_conditional_schedule();
+               if (copy_from_user(con_buf, buf, count)) {
+                       n = 0; /* ?? are error codes legal here ?? */
+                       goto out;
+               }
+
+               buf = con_buf;
+       }
+
        /* At this point 'buf' is guaranteed to be a kernel buffer
         * and therefore no access to userspace (and therefore sleeping)
         * will be needed.  The con_buf_sem serializes all tty based
@@ -2082,6 +2099,22 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
        release_console_sem();
 
 out:
+       if (from_user) {
+               /* If the user requested something larger than
+                * the CON_BUF_SIZE, and the tty is not stopped,
+                * keep going.
+                */
+               if ((orig_count > CON_BUF_SIZE) && !tty->stopped) {
+                       orig_count -= CON_BUF_SIZE;
+                       orig_buf += CON_BUF_SIZE;
+                       count = orig_count;
+                       buf = orig_buf;
+                       goto again;
+               }
+
+               up(&con_buf_sem);
+       }
+
        return n;
 #undef FLUSH
 }
@@ -2158,6 +2191,8 @@ void vt_console_print(struct console *co, const char *b, unsigned count)
        if (!printable || test_and_set_bit(0, &printing))
                return;
 
+       pm_access(pm_con);
+
        if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
                currcons = kmsg_redirect - 1;
 
@@ -2352,11 +2387,13 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
  * /dev/ttyN handling
  */
 
-static int con_write(struct tty_struct *tty, const unsigned char *buf, int count)
+static int con_write(struct tty_struct *tty, int from_user,
+                    const unsigned char *buf, int count)
 {
        int     retval;
 
-       retval = do_con_write(tty, buf, count);
+       pm_access(pm_con);
+       retval = do_con_write(tty, from_user, buf, count);
        con_flush_chars(tty);
 
        return retval;
@@ -2366,7 +2403,8 @@ static void con_put_char(struct tty_struct *tty, unsigned char ch)
 {
        if (in_interrupt())
                return; /* n_r3964 calls put_char() from interrupt context */
-       do_con_write(tty, &ch, 1);
+       pm_access(pm_con);
+       do_con_write(tty, 0, &ch, 1);
 }
 
 static int con_write_room(struct tty_struct *tty)
@@ -2434,6 +2472,8 @@ static void con_flush_chars(struct tty_struct *tty)
        if (in_interrupt())     /* from flush_to_ldisc */
                return;
 
+       pm_access(pm_con);
+       
        /* if we race with con_close(), vt may be null */
        acquire_console_sem();
        vt = tty->driver_data;
@@ -3042,10 +3082,6 @@ int con_font_get(int currcons, struct console_font_op *op)
        if (rc)
                goto out;
 
-       op->height = font.height;
-       op->width = font.width;
-       op->charcount = font.charcount;
-
        if (op->data && copy_to_user(op->data, font.data, c))
                rc = -EFAULT;