diff options
| -rw-r--r-- | drivers/char/vt.c | 211 | ||||
| -rw-r--r-- | drivers/video/console/dummycon.c | 5 | ||||
| -rw-r--r-- | drivers/video/console/fbcon.c | 30 | ||||
| -rw-r--r-- | drivers/video/console/mdacon.c | 6 | ||||
| -rw-r--r-- | drivers/video/console/newport_con.c | 21 | ||||
| -rw-r--r-- | drivers/video/console/promcon.c | 7 | ||||
| -rw-r--r-- | drivers/video/console/sticon.c | 6 | ||||
| -rw-r--r-- | drivers/video/console/vgacon.c | 50 | ||||
| -rw-r--r-- | include/linux/console.h | 5 | ||||
| -rw-r--r-- | include/linux/vt_kern.h | 4 |
10 files changed, 196 insertions, 149 deletions
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index b6da553f0520..12db83db68bc 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -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. */ diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index cbe3386818f4..3ac5d5842e72 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -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, }; diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 691ae83e087d..42727f9d32bc 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -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, diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 8f7f3a7d4190..6dbeb18946b9 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -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, diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 5e4fdc08e64a..bf566efd038f 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -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, diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c index 1458b1613287..fec664e61551 100644 --- a/drivers/video/console/promcon.c +++ b/drivers/video/console/promcon.c @@ -457,12 +457,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) { if (blank) { @@ -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) diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 92dffc67649b..99262680fdd8 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -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, diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 23e1e7e5da9f..c3af575de98c 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -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, diff --git a/include/linux/console.h b/include/linux/console.h index 488678c037a1..357e7711f08e 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -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); diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 9a559f910820..383a93cbbeeb 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h @@ -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); |
