summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/char/vt.c211
-rw-r--r--drivers/video/console/dummycon.c5
-rw-r--r--drivers/video/console/fbcon.c30
-rw-r--r--drivers/video/console/mdacon.c6
-rw-r--r--drivers/video/console/newport_con.c21
-rw-r--r--drivers/video/console/promcon.c7
-rw-r--r--drivers/video/console/sticon.c6
-rw-r--r--drivers/video/console/vgacon.c50
-rw-r--r--include/linux/console.h5
-rw-r--r--include/linux/vt_kern.h4
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);