int con_font_set(int currcons, struct console_font_op *op)
{
- struct console_font_op old_op;
+ struct console_font font;
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)
nonzero:
op->height = h;
}
- if (op->width > 32 || op->height > 32)
+ 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;
- temp = kmalloc(size, GFP_KERNEL);
- if (!temp)
+ 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(temp, op->data, size)) {
- rc = -EFAULT;
- goto out;
+ if (copy_from_user(font.data, op->data, size)) {
+ kfree(font.data);
+ return -EFAULT;
}
- op->data = temp;
acquire_console_sem();
if (sw->con_font_set)
- rc = sw->con_font_set(vc_cons[currcons].d, op);
+ rc = sw->con_font_set(vc_cons[currcons].d, &font, op->flags);
else
rc = -ENOSYS;
release_console_sem();
- op->data = old_op.data;
-out:
- kfree(temp);
+ kfree(font.data);
return rc;
}
return fbcon_do_set_font(vc, &crap, od->fontdata, od->userfont);
}
-static int fbcon_set_font(struct vc_data *vc, struct console_font_op *op)
+/*
+ * User asked to set font; we are guaranteed that
+ * a) width and height are in range 1..32
+ * b) charcount does not exceed 512
+ */
+
+static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigned flags)
{
- int w = op->width;
- int h = op->height;
+ unsigned charcount = font->charcount;
+ int w = font->width;
+ int h = font->height;
int size = h;
int i, k;
- u8 *new_data, *data = op->data, *p;
+ u8 *new_data, *data = font->data, *p;
+ struct console_font_op crap = {.width = font->width,
+ .height = font->height,
+ .op = KD_FONT_OP_SET};
- if ((w <= 0) || (w > 32)
- || (op->charcount != 256 && op->charcount != 512))
+ if (charcount != 256 && charcount != 512)
return -EINVAL;
if (w > 8) {
else
size *= 4;
}
- size *= op->charcount;
+ size *= charcount;
+
+ new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER);
- if (!
- (new_data =
- kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER)))
+ if (!new_data)
return -ENOMEM;
+
new_data += FONT_EXTRA_WORDS * sizeof(int);
FNTSIZE(new_data) = size;
- FNTCHARCNT(new_data) = op->charcount;
+ FNTCHARCNT(new_data) = charcount;
REFCOUNT(new_data) = 0; /* usage counter */
p = new_data;
if (w <= 8) {
- for (i = 0; i < op->charcount; i++) {
+ for (i = 0; i < charcount; i++) {
memcpy(p, data, h);
data += 32;
p += h;
}
} else if (w <= 16) {
h *= 2;
- for (i = 0; i < op->charcount; i++) {
+ for (i = 0; i < charcount; i++) {
memcpy(p, data, h);
data += 64;
p += h;
}
} else if (w <= 24) {
- for (i = 0; i < op->charcount; i++) {
+ for (i = 0; i < charcount; i++) {
int j;
for (j = 0; j < h; j++) {
memcpy(p, data, 3);
}
} else {
h *= 4;
- for (i = 0; i < op->charcount; i++) {
+ for (i = 0; i < charcount; i++) {
memcpy(p, data, h);
data += 128;
p += h;
break;
}
}
- return fbcon_do_set_font(vc, op, new_data, 1);
+ return fbcon_do_set_font(vc, &crap, new_data, 1);
}
static int fbcon_set_def_font(struct vc_data *vc, struct console_font *font, char *name)
return 1;
}
-static int newport_set_font(int unit, struct console_font_op *op)
+static int newport_set_font(int unit, struct console_font *op)
{
int w = op->width;
int h = op->height;
return newport_set_def_font(vc->vc_num, op);
}
-static int newport_font_set(struct vc_data *vc, struct console_font_op *op)
+static int newport_font_set(struct vc_data *vc, struct console_font *font, unsigned flags)
{
- return newport_set_font(vc->vc_num, op);
+ return newport_set_font(vc->vc_num, font);
}
static int newport_set_palette(struct vc_data *vc, unsigned char *table)
return 0;
}
-static int vgacon_font_set(struct vc_data *c, struct console_font_op *op)
+static int vgacon_font_set(struct vc_data *c, struct console_font *font, unsigned flags)
{
+ unsigned charcount = font->charcount;
int rc;
if (vga_video_type < VIDEO_TYPE_EGAM)
return -EINVAL;
- if (op->width != 8 || (op->charcount != 256 && op->charcount != 512))
+ if (font->width != 8 || (charcount != 256 && charcount != 512))
return -EINVAL;
- rc = vgacon_do_font_op(&state, op->data, 1, op->charcount == 512);
+ rc = vgacon_do_font_op(&state, font->data, 1, charcount == 512);
if (rc)
return rc;
- if (!(op->flags & KD_FONT_FLAG_DONT_RECALC))
- rc = vgacon_adjust_height(c, op->height);
+ if (!(flags & KD_FONT_FLAG_DONT_RECALC))
+ rc = vgacon_adjust_height(c, font->height);
return rc;
}
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_set)(struct vc_data *, struct console_font_op *);
+ int (*con_font_set)(struct vc_data *, struct console_font *, unsigned);
int (*con_font_get)(struct vc_data *, struct console_font_op *);
int (*con_font_default)(struct vc_data *, struct console_font *, char *);
int (*con_font_copy)(struct vc_data *, int);