]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] con_font_op split
authorAlexander Viro <viro@www.linux.org.uk>
Thu, 29 Jul 2004 15:47:21 +0000 (08:47 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 29 Jul 2004 15:47:21 +0000 (08:47 -0700)
Preparations for cleanups: con_font_op() is turned into a switch calling
con_font_{get,set,default,copy} depending on the operation required;
method ->con_font_op() also split, with NULL resulting in -ENOSYS on
operation in question.

Code that used to be in con_font_op() got slightly cleaned up after move
into new helpers (we are beginning to untangle the mess; there will be
more cleanups in the next patches).

Methods are currently using exact same arguments as old ->con_font_op().
That will change in subsequent patches, method by method (right now there's
a hell of a scary field reuse between them, making impossible to do any
static checks and practically begging for bugs).

Signed-off-by: Al Viro <viro@parcelfarce.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/char/vt.c
drivers/video/console/dummycon.c
drivers/video/console/fbcon.c
drivers/video/console/mdacon.c
drivers/video/console/newport_con.c
drivers/video/console/promcon.c
drivers/video/console/sticon.c
drivers/video/console/vgacon.c
include/linux/console.h
include/linux/vt_kern.h

index b6da553f05208631160f3fe9767682a8f1d9f9d3..12db83db68bcf3d7d2cf042aa4b4d4082440bd48 100644 (file)
@@ -3023,98 +3023,167 @@ void reset_palette(int currcons)
 
 #define max_font_size 65536
 
-int con_font_op(int currcons, struct console_font_op *op)
+int con_font_get(int currcons, struct console_font_op *op)
 {
+       struct console_font_op old_op;
        int rc = -EINVAL;
-       int size = max_font_size, set;
        u8 *temp = NULL;
-       struct console_font_op old_op;
+       int c;
 
        if (vt_cons[currcons]->vc_mode != KD_TEXT)
-               goto quit;
+               return -EINVAL;
+
        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) {
-               temp = kmalloc(size, GFP_KERNEL);
+               temp = kmalloc(max_font_size, GFP_KERNEL);
                if (!temp)
                        return -ENOMEM;
-               if (set && copy_from_user(temp, op->data, size)) {
-                       rc = -EFAULT;
-                       goto quit;
-               }
                op->data = temp;
        }
 
        acquire_console_sem();
-       rc = sw->con_font_op(vc_cons[currcons].d, op);
+       if (sw->con_font_get)
+               rc = sw->con_font_get(vc_cons[currcons].d, op);
+       else
+               rc = -ENOSYS;
        release_console_sem();
 
        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)
+       if (rc)
+               goto out;
+
+       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;
-               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;
+       } else {
+               if (op->width != 8)
+                       rc = -EIO;
+               else if ((old_op.height && op->height > old_op.height) ||
+                        op->height > 32)
+                       rc = -ENOSPC;
+       }
+       if (rc)
+               goto out;
+
+       if (op->data && copy_to_user(op->data, temp, c))
+               rc = -EFAULT;
+
+out:
+       kfree(temp);
+       return rc;
+}
+
+int con_font_set(int currcons, struct console_font_op *op)
+{
+       struct console_font_op old_op;
+       int rc = -EINVAL;
+       int size;
+       u8 *temp;
+
+       if (vt_cons[currcons]->vc_mode != KD_TEXT)
+               return -EINVAL;
+       memcpy(&old_op, op, sizeof(old_op));
+       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;
        }
-quit:  if (temp)
-               kfree(temp);
+       if (op->width > 32 || op->height > 32)
+               return -EINVAL;
+       size = (op->width+7)/8 * 32 * op->charcount;
+       if (size > max_font_size)
+               return -ENOSPC;
+       temp = kmalloc(size, GFP_KERNEL);
+       if (!temp)
+               return -ENOMEM;
+       if (copy_from_user(temp, op->data, size)) {
+               rc = -EFAULT;
+               goto out;
+       }
+       op->data = temp;
+       acquire_console_sem();
+       if (sw->con_font_set)
+               rc = sw->con_font_set(vc_cons[currcons].d, op);
+       else
+               rc = -ENOSYS;
+       release_console_sem();
+       op->data = old_op.data;
+out:
+       kfree(temp);
        return rc;
 }
 
+int con_font_default(int currcons, struct console_font_op *op)
+{
+       int rc;
+
+       if (vt_cons[currcons]->vc_mode != KD_TEXT)
+               return -EINVAL;
+
+       acquire_console_sem();
+       if (sw->con_font_default)
+               rc = sw->con_font_default(vc_cons[currcons].d, op);
+       else
+               rc = -ENOSYS;
+       release_console_sem();
+       return rc;
+}
+
+int con_font_copy(int currcons, struct console_font_op *op)
+{
+       int rc;
+
+       if (vt_cons[currcons]->vc_mode != KD_TEXT)
+               return -EINVAL;
+
+       acquire_console_sem();
+       if (sw->con_font_copy)
+               rc = sw->con_font_copy(vc_cons[currcons].d, op);
+       else
+               rc = -ENOSYS;
+       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.
  */
index cbe3386818f4e3d9566cba01d85c2c603f67b26c..3ac5d5842e726a4f289e253b473c605417454eb6 100644 (file)
@@ -71,7 +71,10 @@ const struct consw dummy_con = {
     .con_bmove =       DUMMY,
     .con_switch =      DUMMY,
     .con_blank =       DUMMY,
-    .con_font_op =     DUMMY,
+    .con_font_set =    DUMMY,
+    .con_font_get =    DUMMY,
+    .con_font_default =        DUMMY,
+    .con_font_copy =   DUMMY,
     .con_set_palette = DUMMY,
     .con_scrolldelta = DUMMY,
 };
index 691ae83e087da0fd279acfbad3678b0d0c4e304f..42727f9d32bc69fa31ba3b7a97c7d7d0f895aea7 100644 (file)
@@ -165,7 +165,6 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx,
                        int height, int width);
 static int fbcon_switch(struct vc_data *vc);
 static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch);
-static int fbcon_font_op(struct vc_data *vc, struct console_font_op *op);
 static int fbcon_set_palette(struct vc_data *vc, unsigned char *table);
 static int fbcon_scrolldelta(struct vc_data *vc, int lines);
 void accel_clear_margins(struct vc_data *vc, struct fb_info *info,
@@ -2001,7 +2000,7 @@ static void fbcon_free_font(struct display *p)
        p->userfont = 0;
 }
 
-static inline int fbcon_get_font(struct vc_data *vc, struct console_font_op *op)
+static int fbcon_get_font(struct vc_data *vc, struct console_font_op *op)
 {
        u8 *fontdata = vc->vc_font.data;
        u8 *data = op->data;
@@ -2168,7 +2167,7 @@ static int fbcon_do_set_font(struct vc_data *vc, struct console_font_op *op,
        return 0;
 }
 
-static inline int fbcon_copy_font(struct vc_data *vc, struct console_font_op *op)
+static int fbcon_copy_font(struct vc_data *vc, struct console_font_op *op)
 {
        struct display *od;
        int h = op->height;
@@ -2185,7 +2184,7 @@ static inline int fbcon_copy_font(struct vc_data *vc, struct console_font_op *op
        return fbcon_do_set_font(vc, op, od->fontdata, od->userfont);
 }
 
-static inline int fbcon_set_font(struct vc_data *vc, struct console_font_op *op)
+static int fbcon_set_font(struct vc_data *vc, struct console_font_op *op)
 {
        int w = op->width;
        int h = op->height;
@@ -2273,7 +2272,7 @@ static inline int fbcon_set_font(struct vc_data *vc, struct console_font_op *op)
        return fbcon_do_set_font(vc, op, new_data, 1);
 }
 
-static inline int fbcon_set_def_font(struct vc_data *vc, struct console_font_op *op)
+static int fbcon_set_def_font(struct vc_data *vc, struct console_font_op *op)
 {
        struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
        char name[MAX_FONT_NAME];
@@ -2293,22 +2292,6 @@ static inline int fbcon_set_def_font(struct vc_data *vc, struct console_font_op
        return fbcon_do_set_font(vc, op, f->data, 0);
 }
 
-static int fbcon_font_op(struct vc_data *vc, struct console_font_op *op)
-{
-       switch (op->op) {
-       case KD_FONT_OP_SET:
-               return fbcon_set_font(vc, op);
-       case KD_FONT_OP_GET:
-               return fbcon_get_font(vc, op);
-       case KD_FONT_OP_SET_DEFAULT:
-               return fbcon_set_def_font(vc, op);
-       case KD_FONT_OP_COPY:
-               return fbcon_copy_font(vc, op);
-       default:
-               return -ENOSYS;
-       }
-}
-
 static u16 palette_red[16];
 static u16 palette_green[16];
 static u16 palette_blue[16];
@@ -2609,7 +2592,10 @@ const struct consw fb_con = {
        .con_bmove              = fbcon_bmove,
        .con_switch             = fbcon_switch,
        .con_blank              = fbcon_blank,
-       .con_font_op            = fbcon_font_op,
+       .con_font_set           = fbcon_set_font,
+       .con_font_get           = fbcon_get_font,
+       .con_font_default       = fbcon_set_def_font,
+       .con_font_copy          = fbcon_copy_font,
        .con_set_palette        = fbcon_set_palette,
        .con_scrolldelta        = fbcon_scrolldelta,
        .con_set_origin         = fbcon_set_origin,
index 8f7f3a7d4190022ba49cf590fd86d1069caf397b..6dbeb18946b9c24618941f743021449ee2c6b21a 100644 (file)
@@ -517,11 +517,6 @@ static int mdacon_blank(struct vc_data *c, int blank, int mode_switch)
        }
 }
 
-static int mdacon_font_op(struct vc_data *c, struct console_font_op *op)
-{
-       return -ENOSYS;
-}
-
 static int mdacon_scrolldelta(struct vc_data *c, int lines)
 {
        return 0;
@@ -594,7 +589,6 @@ const struct consw mda_con = {
        .con_bmove =            mdacon_bmove,
        .con_switch =           mdacon_switch,
        .con_blank =            mdacon_blank,
-       .con_font_op =          mdacon_font_op,
        .con_set_palette =      mdacon_set_palette,
        .con_scrolldelta =      mdacon_scrolldelta,
        .con_build_attr =       mdacon_build_attr,
index 5e4fdc08e64af82c34f45287a5f0ba388f10faec..bf566efd038f0f91336d19fdf6929bd918eb779b 100644 (file)
@@ -543,18 +543,14 @@ static int newport_set_def_font(int unit, struct console_font_op *op)
        return 0;
 }
 
-static int newport_font_op(struct vc_data *vc, struct console_font_op *op)
+static int newport_font_default(struct vc_data *vc, struct console_font_op *op)
 {
-       int unit = vc->vc_num;
-
-       switch (op->op) {
-       case KD_FONT_OP_SET:
-               return newport_set_font(unit, op);
-       case KD_FONT_OP_SET_DEFAULT:
-               return newport_set_def_font(unit, op);
-       default:
-               return -ENOSYS;
-       }
+       return newport_set_def_font(vc->vc_num, op);
+}
+
+static int newport_font_set(struct vc_data *vc, struct console_font_op *op)
+{
+       return newport_set_font(vc->vc_num, op);
 }
 
 static int newport_set_palette(struct vc_data *vc, unsigned char *table)
@@ -717,7 +713,8 @@ const struct consw newport_con = {
     .con_bmove =       newport_bmove,
     .con_switch =      newport_switch,
     .con_blank =       newport_blank,
-    .con_font_op =     newport_font_op,
+    .con_font_set =    newport_font_set,
+    .con_font_default =        newport_font_default,
     .con_set_palette = newport_set_palette,
     .con_scrolldelta = newport_scrolldelta,
     .con_set_origin =  DUMMY,
index 1458b16132872226213545e6045bd8dc2b882ae3..fec664e615514acb715341781d934fa7361631b2 100644 (file)
@@ -456,12 +456,6 @@ promcon_cursor(struct vc_data *conp, int mode)
        }
 }
 
-static int
-promcon_font_op(struct vc_data *conp, struct console_font_op *op)
-{
-       return -ENOSYS;
-}
-        
 static int
 promcon_blank(struct vc_data *conp, int blank, int mode_switch)
 {
@@ -586,7 +580,6 @@ const struct consw prom_con = {
        .con_bmove =            promcon_bmove,
        .con_switch =           promcon_switch,
        .con_blank =            promcon_blank,
-       .con_font_op =          promcon_font_op,
        .con_set_palette =      DUMMY,
        .con_scrolldelta =      DUMMY,
 #if !(PROMCON_COLOR)
index 92dffc67649b3a77f7f5e95e5828b3e9a877f06a..99262680fdd8adc966c1da62cbfd99c187816550 100644 (file)
@@ -85,11 +85,6 @@ static int sticon_set_palette(struct vc_data *c, unsigned char *table)
     return -EINVAL;
 }
 
-static int sticon_font_op(struct vc_data *c, struct console_font_op *op)
-{
-    return -ENOSYS;
-}
-
 static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
 {
     int unit = conp->vc_num;
@@ -366,7 +361,6 @@ static struct consw sti_con = {
        .con_bmove              = sticon_bmove,
        .con_switch             = sticon_switch,
        .con_blank              = sticon_blank,
-       .con_font_op            = sticon_font_op,
        .con_set_palette        = sticon_set_palette,
        .con_scrolldelta        = sticon_scrolldelta,
        .con_set_origin         = sticon_set_origin,
index 23e1e7e5da9fc2fbba96dde9c7cbb1fcd1d89013..c3af575de98c215441fff66acdab13180397752f 100644 (file)
@@ -77,7 +77,6 @@ static void vgacon_deinit(struct vc_data *c);
 static void vgacon_cursor(struct vc_data *c, int mode);
 static int vgacon_switch(struct vc_data *c);
 static int vgacon_blank(struct vc_data *c, int blank, int mode_switch);
-static int vgacon_font_op(struct vc_data *c, struct console_font_op *op);
 static int vgacon_set_palette(struct vc_data *vc, unsigned char *table);
 static int vgacon_scrolldelta(struct vc_data *c, int lines);
 static int vgacon_set_origin(struct vc_data *c);
@@ -908,39 +907,43 @@ static int vgacon_adjust_height(struct vc_data *vc, unsigned fontheight)
        return 0;
 }
 
-static int vgacon_font_op(struct vc_data *c, struct console_font_op *op)
+static int vgacon_font_set(struct vc_data *c, struct console_font_op *op)
 {
        int rc;
 
        if (vga_video_type < VIDEO_TYPE_EGAM)
                return -EINVAL;
 
-       if (op->op == KD_FONT_OP_SET) {
-               if (op->width != 8
-                   || (op->charcount != 256 && op->charcount != 512))
-                       return -EINVAL;
-               rc = vgacon_do_font_op(&state, op->data, 1, op->charcount == 512);
-               if (!rc && !(op->flags & KD_FONT_FLAG_DONT_RECALC))
-                       rc = vgacon_adjust_height(c, op->height);
-       } else if (op->op == KD_FONT_OP_GET) {
-               op->width = 8;
-               op->height = c->vc_font.height;
-               op->charcount = vga_512_chars ? 512 : 256;
-               if (!op->data)
-                       return 0;
-               rc = vgacon_do_font_op(&state, op->data, 0, 0);
-       } else
-               rc = -ENOSYS;
+       if (op->width != 8 || (op->charcount != 256 && op->charcount != 512))
+               return -EINVAL;
+
+       rc = vgacon_do_font_op(&state, op->data, 1, op->charcount == 512);
+       if (rc)
+               return rc;
+
+       if (!(op->flags & KD_FONT_FLAG_DONT_RECALC))
+               rc = vgacon_adjust_height(c, op->height);
        return rc;
 }
 
-#else
-
-static int vgacon_font_op(struct vc_data *c, struct console_font_op *op)
+static int vgacon_font_get(struct vc_data *c, struct console_font_op *op)
 {
-       return -ENOSYS;
+       if (vga_video_type < VIDEO_TYPE_EGAM)
+               return -EINVAL;
+
+       op->width = 8;
+       op->height = c->vc_font.height;
+       op->charcount = vga_512_chars ? 512 : 256;
+       if (!op->data)
+               return 0;
+       return vgacon_do_font_op(&state, op->data, 0, 0);
 }
 
+#else
+
+#define vgacon_font_set NULL
+#define vgacon_font_get NULL
+
 #endif
 
 static int vgacon_scrolldelta(struct vc_data *c, int lines)
@@ -1079,7 +1082,8 @@ const struct consw vga_con = {
        .con_bmove = DUMMY,
        .con_switch = vgacon_switch,
        .con_blank = vgacon_blank,
-       .con_font_op = vgacon_font_op,
+       .con_font_set = vgacon_font_set,
+       .con_font_get = vgacon_font_get,
        .con_set_palette = vgacon_set_palette,
        .con_scrolldelta = vgacon_scrolldelta,
        .con_set_origin = vgacon_set_origin,
index 488678c037a1bf8af1ee651eed4fd380c317d750..357e7711f08ed6ec8c19ef10310b9f7a622d9119 100644 (file)
@@ -40,7 +40,10 @@ struct consw {
        void    (*con_bmove)(struct vc_data *, int, int, int, int, int, int);
        int     (*con_switch)(struct vc_data *);
        int     (*con_blank)(struct vc_data *, int, int);
-       int     (*con_font_op)(struct vc_data *, struct console_font_op *);
+       int     (*con_font_set)(struct vc_data *, struct console_font_op *);
+       int     (*con_font_get)(struct vc_data *, struct console_font_op *);
+       int     (*con_font_default)(struct vc_data *, struct console_font_op *);
+       int     (*con_font_copy)(struct vc_data *, struct console_font_op *);
        int     (*con_resize)(struct vc_data *, unsigned int, unsigned int);
        int     (*con_set_palette)(struct vc_data *, unsigned char *);
        int     (*con_scrolldelta)(struct vc_data *, int);
index 9a559f9108202d5722aa7853a42ee936049c0d76..383a93cbbeeb1a6d9a37fd505af4db5ff5d611b6 100644 (file)
@@ -50,6 +50,10 @@ void do_unblank_screen(int leaving_gfx);
 void unblank_screen(void);
 void poke_blanked_console(void);
 int con_font_op(int currcons, struct console_font_op *op);
+int con_font_set(int currcons, struct console_font_op *op);
+int con_font_get(int currcons, struct console_font_op *op);
+int con_font_default(int currcons, struct console_font_op *op);
+int con_font_copy(int currcons, struct console_font_op *op);
 int con_set_cmap(unsigned char __user *cmap);
 int con_get_cmap(unsigned char __user *cmap);
 void scrollback(int);