This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / char / vt.c
index a204572..b6da553 100644 (file)
 #include <linux/workqueue.h>
 #include <linux/bootmem.h>
 #include <linux/pm.h>
-#include <linux/font.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -3024,182 +3023,98 @@ void reset_palette(int currcons)
 
 #define max_font_size 65536
 
-int con_font_get(int currcons, struct console_font_op *op)
+int con_font_op(int currcons, struct console_font_op *op)
 {
-       struct console_font font;
        int rc = -EINVAL;
-       int c;
+       int size = max_font_size, set;
+       u8 *temp = NULL;
+       struct console_font_op old_op;
 
        if (vt_cons[currcons]->vc_mode != KD_TEXT)
-               return -EINVAL;
-
+               goto quit;
+       memcpy(&old_op, op, sizeof(old_op));
+       if (op->op == KD_FONT_OP_SET) {
+               if (!op->data)
+                       return -EINVAL;
+               if (op->charcount > 512)
+                       goto quit;
+               if (!op->height) {              /* Need to guess font height [compat] */
+                       int h, i;
+                       u8 __user *charmap = op->data;
+                       u8 tmp;
+                       
+                       /* If from KDFONTOP ioctl, don't allow things which can be done in userland,
+                          so that we can get rid of this soon */
+                       if (!(op->flags & KD_FONT_FLAG_OLD))
+                               goto quit;
+                       rc = -EFAULT;
+                       for (h = 32; h > 0; h--)
+                               for (i = 0; i < op->charcount; i++) {
+                                       if (get_user(tmp, &charmap[32*i+h-1]))
+                                               goto quit;
+                                       if (tmp)
+                                               goto nonzero;
+                               }
+                       rc = -EINVAL;
+                       goto quit;
+               nonzero:
+                       rc = -EINVAL;
+                       op->height = h;
+               }
+               if (op->width > 32 || op->height > 32)
+                       goto quit;
+               size = (op->width+7)/8 * 32 * op->charcount;
+               if (size > max_font_size)
+                       return -ENOSPC;
+               set = 1;
+       } else if (op->op == KD_FONT_OP_GET)
+               set = 0;
+       else {
+               acquire_console_sem();
+               rc = sw->con_font_op(vc_cons[currcons].d, op);
+               release_console_sem();
+               return rc;
+       }
        if (op->data) {
-               font.data = kmalloc(max_font_size, GFP_KERNEL);
-               if (!font.data)
+               temp = kmalloc(size, GFP_KERNEL);
+               if (!temp)
                        return -ENOMEM;
-       } else
-               font.data = NULL;
-
-       acquire_console_sem();
-       if (sw->con_font_get)
-               rc = sw->con_font_get(vc_cons[currcons].d, &font);
-       else
-               rc = -ENOSYS;
-       release_console_sem();
-
-       if (rc)
-               goto out;
-
-       c = (font.width+7)/8 * 32 * font.charcount;
-       
-       if (op->data && font.charcount > op->charcount)
-               rc = -ENOSPC;
-       if (!(op->flags & KD_FONT_FLAG_OLD)) {
-               if (font.width > op->width || font.height > op->height) 
-                       rc = -ENOSPC;
-       } else {
-               if (font.width != 8)
-                       rc = -EIO;
-               else if ((op->height && font.height > op->height) ||
-                        font.height > 32)
-                       rc = -ENOSPC;
+               if (set && copy_from_user(temp, op->data, size)) {
+                       rc = -EFAULT;
+                       goto quit;
+               }
+               op->data = temp;
        }
-       if (rc)
-               goto out;
-
-       if (op->data && copy_to_user(op->data, font.data, c))
-               rc = -EFAULT;
-
-out:
-       kfree(font.data);
-       return rc;
-}
-
-int con_font_set(int currcons, struct console_font_op *op)
-{
-       struct console_font font;
-       int rc = -EINVAL;
-       int size;
 
-       if (vt_cons[currcons]->vc_mode != KD_TEXT)
-               return -EINVAL;
-       if (!op->data)
-               return -EINVAL;
-       if (op->charcount > 512)
-               return -EINVAL;
-       if (!op->height) {              /* Need to guess font height [compat] */
-               int h, i;
-               u8 __user *charmap = op->data;
-               u8 tmp;
-               
-               /* If from KDFONTOP ioctl, don't allow things which can be done in userland,
-                  so that we can get rid of this soon */
-               if (!(op->flags & KD_FONT_FLAG_OLD))
-                       return -EINVAL;
-               for (h = 32; h > 0; h--)
-                       for (i = 0; i < op->charcount; i++) {
-                               if (get_user(tmp, &charmap[32*i+h-1]))
-                                       return -EFAULT;
-                               if (tmp)
-                                       goto nonzero;
-                       }
-               return -EINVAL;
-       nonzero:
-               op->height = h;
-       }
-       if (op->width <= 0 || op->width > 32 || op->height > 32)
-               return -EINVAL;
-       size = (op->width+7)/8 * 32 * op->charcount;
-       if (size > max_font_size)
-               return -ENOSPC;
-       font.charcount = op->charcount;
-       font.height = op->height;
-       font.width = op->width;
-       font.data = kmalloc(size, GFP_KERNEL);
-       if (!font.data)
-               return -ENOMEM;
-       if (copy_from_user(font.data, op->data, size)) {
-               kfree(font.data);
-               return -EFAULT;
-       }
        acquire_console_sem();
-       if (sw->con_font_set)
-               rc = sw->con_font_set(vc_cons[currcons].d, &font, op->flags);
-       else
-               rc = -ENOSYS;
+       rc = sw->con_font_op(vc_cons[currcons].d, op);
        release_console_sem();
-       kfree(font.data);
-       return rc;
-}
-
-int con_font_default(int currcons, struct console_font_op *op)
-{
-       struct console_font font = {.width = op->width, .height = op->height};
-       char name[MAX_FONT_NAME];
-       char *s = name;
-       int rc;
-
-       if (vt_cons[currcons]->vc_mode != KD_TEXT)
-               return -EINVAL;
-
-       if (!op->data)
-               s = NULL;
-       else if (strncpy_from_user(name, op->data, MAX_FONT_NAME - 1) < 0)
-               return -EFAULT;
-       else
-               name[MAX_FONT_NAME - 1] = 0;
 
-       acquire_console_sem();
-       if (sw->con_font_default)
-               rc = sw->con_font_default(vc_cons[currcons].d, &font, s);
-       else
-               rc = -ENOSYS;
-       release_console_sem();
-       if (!rc) {
-               op->width = font.width;
-               op->height = font.height;
+       op->data = old_op.data;
+       if (!rc && !set) {
+               int c = (op->width+7)/8 * 32 * op->charcount;
+               
+               if (op->data && op->charcount > old_op.charcount)
+                       rc = -ENOSPC;
+               if (!(op->flags & KD_FONT_FLAG_OLD)) {
+                       if (op->width > old_op.width || 
+                           op->height > old_op.height)
+                               rc = -ENOSPC;
+               } else {
+                       if (op->width != 8)
+                               rc = -EIO;
+                       else if ((old_op.height && op->height > old_op.height) ||
+                                op->height > 32)
+                               rc = -ENOSPC;
+               }
+               if (!rc && op->data && copy_to_user(op->data, temp, c))
+                       rc = -EFAULT;
        }
+quit:  if (temp)
+               kfree(temp);
        return rc;
 }
 
-int con_font_copy(int currcons, struct console_font_op *op)
-{
-       int con = op->height;
-       struct vc_data *vc;
-       int rc;
-
-       if (vt_cons[currcons]->vc_mode != KD_TEXT)
-               return -EINVAL;
-
-       acquire_console_sem();
-       vc = vc_cons[currcons].d;
-       if (!sw->con_font_copy)
-               rc = -ENOSYS;
-       else if (con < 0 || !vc_cons_allocated(con))
-               rc = -ENOTTY;
-       else if (con == vc->vc_num)     /* nothing to do */
-               rc = 0;
-       else
-               rc = sw->con_font_copy(vc, con);
-       release_console_sem();
-       return rc;
-}
-
-int con_font_op(int currcons, struct console_font_op *op)
-{
-       switch (op->op) {
-       case KD_FONT_OP_SET:
-               return con_font_set(currcons, op);
-       case KD_FONT_OP_GET:
-               return con_font_get(currcons, op);
-       case KD_FONT_OP_SET_DEFAULT:
-               return con_font_default(currcons, op);
-       case KD_FONT_OP_COPY:
-               return con_font_copy(currcons, op);
-       }
-       return -ENOSYS;
-}
-
 /*
  *     Interface exported to selection and vcs.
  */