| .. | .. |
|---|
| 2 | 2 | * linux/drivers/video/console/sticon.c - console driver using HP's STI firmware |
|---|
| 3 | 3 | * |
|---|
| 4 | 4 | * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> |
|---|
| 5 | | - * Copyright (C) 2002 Helge Deller <deller@gmx.de> |
|---|
| 5 | + * Copyright (C) 2002-2020 Helge Deller <deller@gmx.de> |
|---|
| 6 | 6 | * |
|---|
| 7 | 7 | * Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c, |
|---|
| 8 | 8 | * which were |
|---|
| .. | .. |
|---|
| 43 | 43 | #include <linux/kd.h> |
|---|
| 44 | 44 | #include <linux/selection.h> |
|---|
| 45 | 45 | #include <linux/module.h> |
|---|
| 46 | +#include <linux/slab.h> |
|---|
| 47 | +#include <linux/font.h> |
|---|
| 48 | +#include <linux/crc32.h> |
|---|
| 46 | 49 | |
|---|
| 47 | 50 | #include <asm/io.h> |
|---|
| 48 | 51 | |
|---|
| .. | .. |
|---|
| 52 | 55 | #define BLANK 0 |
|---|
| 53 | 56 | static int vga_is_gfx; |
|---|
| 54 | 57 | |
|---|
| 58 | +#define STI_DEF_FONT sticon_sti->font |
|---|
| 59 | + |
|---|
| 60 | +/* borrowed from fbcon.c */ |
|---|
| 61 | +#define FNTREFCOUNT(fd) (fd->refcount) |
|---|
| 62 | +#define FNTCRC(fd) (fd->crc) |
|---|
| 63 | +static struct sti_cooked_font *font_data[MAX_NR_CONSOLES]; |
|---|
| 64 | + |
|---|
| 55 | 65 | /* this is the sti_struct used for this console */ |
|---|
| 56 | 66 | static struct sti_struct *sticon_sti; |
|---|
| 57 | | - |
|---|
| 58 | | -/* Software scrollback */ |
|---|
| 59 | | -static unsigned long softback_buf, softback_curr; |
|---|
| 60 | | -static unsigned long softback_in; |
|---|
| 61 | | -static unsigned long /* softback_top, */ softback_end; |
|---|
| 62 | | -static int softback_lines; |
|---|
| 63 | | - |
|---|
| 64 | | -/* software cursor */ |
|---|
| 65 | | -static int cursor_drawn; |
|---|
| 66 | | -#define CURSOR_DRAW_DELAY (1) |
|---|
| 67 | | -#define DEFAULT_CURSOR_BLINK_RATE (20) |
|---|
| 68 | | - |
|---|
| 69 | | -static int vbl_cursor_cnt; |
|---|
| 70 | | - |
|---|
| 71 | | -static inline void cursor_undrawn(void) |
|---|
| 72 | | -{ |
|---|
| 73 | | - vbl_cursor_cnt = 0; |
|---|
| 74 | | - cursor_drawn = 0; |
|---|
| 75 | | -} |
|---|
| 76 | 67 | |
|---|
| 77 | 68 | static const char *sticon_startup(void) |
|---|
| 78 | 69 | { |
|---|
| .. | .. |
|---|
| 81 | 72 | |
|---|
| 82 | 73 | static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos) |
|---|
| 83 | 74 | { |
|---|
| 84 | | - int redraw_cursor = 0; |
|---|
| 85 | | - |
|---|
| 86 | 75 | if (vga_is_gfx || console_blanked) |
|---|
| 87 | 76 | return; |
|---|
| 88 | 77 | |
|---|
| 89 | 78 | if (conp->vc_mode != KD_TEXT) |
|---|
| 90 | 79 | return; |
|---|
| 91 | | -#if 0 |
|---|
| 92 | | - if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) { |
|---|
| 93 | | - cursor_undrawn(); |
|---|
| 94 | | - redraw_cursor = 1; |
|---|
| 95 | | - } |
|---|
| 96 | | -#endif |
|---|
| 97 | 80 | |
|---|
| 98 | | - sti_putc(sticon_sti, c, ypos, xpos); |
|---|
| 99 | | - |
|---|
| 100 | | - if (redraw_cursor) |
|---|
| 101 | | - vbl_cursor_cnt = CURSOR_DRAW_DELAY; |
|---|
| 81 | + sti_putc(sticon_sti, c, ypos, xpos, font_data[conp->vc_num]); |
|---|
| 102 | 82 | } |
|---|
| 103 | 83 | |
|---|
| 104 | 84 | static void sticon_putcs(struct vc_data *conp, const unsigned short *s, |
|---|
| 105 | 85 | int count, int ypos, int xpos) |
|---|
| 106 | 86 | { |
|---|
| 107 | | - int redraw_cursor = 0; |
|---|
| 108 | | - |
|---|
| 109 | 87 | if (vga_is_gfx || console_blanked) |
|---|
| 110 | 88 | return; |
|---|
| 111 | 89 | |
|---|
| 112 | 90 | if (conp->vc_mode != KD_TEXT) |
|---|
| 113 | 91 | return; |
|---|
| 114 | 92 | |
|---|
| 115 | | -#if 0 |
|---|
| 116 | | - if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) && |
|---|
| 117 | | - (p->cursor_x < (xpos + count))) { |
|---|
| 118 | | - cursor_undrawn(); |
|---|
| 119 | | - redraw_cursor = 1; |
|---|
| 120 | | - } |
|---|
| 121 | | -#endif |
|---|
| 122 | | - |
|---|
| 123 | 93 | while (count--) { |
|---|
| 124 | | - sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++); |
|---|
| 94 | + sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++, |
|---|
| 95 | + font_data[conp->vc_num]); |
|---|
| 125 | 96 | } |
|---|
| 126 | | - |
|---|
| 127 | | - if (redraw_cursor) |
|---|
| 128 | | - vbl_cursor_cnt = CURSOR_DRAW_DELAY; |
|---|
| 129 | 97 | } |
|---|
| 130 | 98 | |
|---|
| 131 | 99 | static void sticon_cursor(struct vc_data *conp, int mode) |
|---|
| 132 | 100 | { |
|---|
| 133 | 101 | unsigned short car1; |
|---|
| 134 | 102 | |
|---|
| 135 | | - car1 = conp->vc_screenbuf[conp->vc_x + conp->vc_y * conp->vc_cols]; |
|---|
| 103 | + /* no cursor update if screen is blanked */ |
|---|
| 104 | + if (vga_is_gfx || console_blanked) |
|---|
| 105 | + return; |
|---|
| 106 | + |
|---|
| 107 | + car1 = conp->vc_screenbuf[conp->state.x + conp->state.y * conp->vc_cols]; |
|---|
| 136 | 108 | switch (mode) { |
|---|
| 137 | 109 | case CM_ERASE: |
|---|
| 138 | | - sti_putc(sticon_sti, car1, conp->vc_y, conp->vc_x); |
|---|
| 110 | + sti_putc(sticon_sti, car1, conp->state.y, conp->state.x, |
|---|
| 111 | + font_data[conp->vc_num]); |
|---|
| 139 | 112 | break; |
|---|
| 140 | 113 | case CM_MOVE: |
|---|
| 141 | 114 | case CM_DRAW: |
|---|
| 142 | | - switch (conp->vc_cursor_type & 0x0f) { |
|---|
| 115 | + switch (CUR_SIZE(conp->vc_cursor_type)) { |
|---|
| 143 | 116 | case CUR_UNDERLINE: |
|---|
| 144 | 117 | case CUR_LOWER_THIRD: |
|---|
| 145 | 118 | case CUR_LOWER_HALF: |
|---|
| 146 | 119 | case CUR_TWO_THIRDS: |
|---|
| 147 | 120 | case CUR_BLOCK: |
|---|
| 148 | 121 | sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11), |
|---|
| 149 | | - conp->vc_y, conp->vc_x); |
|---|
| 122 | + conp->state.y, conp->state.x, font_data[conp->vc_num]); |
|---|
| 150 | 123 | break; |
|---|
| 151 | 124 | } |
|---|
| 152 | 125 | break; |
|---|
| .. | .. |
|---|
| 165 | 138 | |
|---|
| 166 | 139 | switch (dir) { |
|---|
| 167 | 140 | case SM_UP: |
|---|
| 168 | | - sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols); |
|---|
| 169 | | - sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_video_erase_char); |
|---|
| 141 | + sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols, |
|---|
| 142 | + font_data[conp->vc_num]); |
|---|
| 143 | + sti_clear(sti, b - count, 0, count, conp->vc_cols, |
|---|
| 144 | + conp->vc_video_erase_char, font_data[conp->vc_num]); |
|---|
| 170 | 145 | break; |
|---|
| 171 | 146 | |
|---|
| 172 | 147 | case SM_DOWN: |
|---|
| 173 | | - sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols); |
|---|
| 174 | | - sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_video_erase_char); |
|---|
| 148 | + sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols, |
|---|
| 149 | + font_data[conp->vc_num]); |
|---|
| 150 | + sti_clear(sti, t, 0, count, conp->vc_cols, |
|---|
| 151 | + conp->vc_video_erase_char, font_data[conp->vc_num]); |
|---|
| 175 | 152 | break; |
|---|
| 176 | 153 | } |
|---|
| 177 | 154 | |
|---|
| 178 | 155 | return false; |
|---|
| 156 | +} |
|---|
| 157 | + |
|---|
| 158 | +static int sticon_set_def_font(int unit, struct console_font *op) |
|---|
| 159 | +{ |
|---|
| 160 | + if (font_data[unit] != STI_DEF_FONT) { |
|---|
| 161 | + if (--FNTREFCOUNT(font_data[unit]) == 0) { |
|---|
| 162 | + kfree(font_data[unit]->raw_ptr); |
|---|
| 163 | + kfree(font_data[unit]); |
|---|
| 164 | + } |
|---|
| 165 | + font_data[unit] = STI_DEF_FONT; |
|---|
| 166 | + } |
|---|
| 167 | + |
|---|
| 168 | + return 0; |
|---|
| 169 | +} |
|---|
| 170 | + |
|---|
| 171 | +static int sticon_set_font(struct vc_data *vc, struct console_font *op) |
|---|
| 172 | +{ |
|---|
| 173 | + struct sti_struct *sti = sticon_sti; |
|---|
| 174 | + int vc_cols, vc_rows, vc_old_cols, vc_old_rows; |
|---|
| 175 | + int unit = vc->vc_num; |
|---|
| 176 | + int w = op->width; |
|---|
| 177 | + int h = op->height; |
|---|
| 178 | + int size, i, bpc, pitch; |
|---|
| 179 | + struct sti_rom_font *new_font; |
|---|
| 180 | + struct sti_cooked_font *cooked_font; |
|---|
| 181 | + unsigned char *data = op->data, *p; |
|---|
| 182 | + |
|---|
| 183 | + if ((w < 6) || (h < 6) || (w > 32) || (h > 32) |
|---|
| 184 | + || (op->charcount != 256 && op->charcount != 512)) |
|---|
| 185 | + return -EINVAL; |
|---|
| 186 | + pitch = ALIGN(w, 8) / 8; |
|---|
| 187 | + bpc = pitch * h; |
|---|
| 188 | + size = bpc * op->charcount; |
|---|
| 189 | + |
|---|
| 190 | + new_font = kmalloc(sizeof(*new_font) + size, STI_LOWMEM); |
|---|
| 191 | + if (!new_font) |
|---|
| 192 | + return -ENOMEM; |
|---|
| 193 | + |
|---|
| 194 | + new_font->first_char = 0; |
|---|
| 195 | + new_font->last_char = op->charcount - 1; |
|---|
| 196 | + new_font->width = w; |
|---|
| 197 | + new_font->height = h; |
|---|
| 198 | + new_font->font_type = STI_FONT_HPROMAN8; |
|---|
| 199 | + new_font->bytes_per_char = bpc; |
|---|
| 200 | + new_font->underline_height = 0; |
|---|
| 201 | + new_font->underline_pos = 0; |
|---|
| 202 | + |
|---|
| 203 | + cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); |
|---|
| 204 | + if (!cooked_font) { |
|---|
| 205 | + kfree(new_font); |
|---|
| 206 | + return -ENOMEM; |
|---|
| 207 | + } |
|---|
| 208 | + cooked_font->raw = new_font; |
|---|
| 209 | + cooked_font->raw_ptr = new_font; |
|---|
| 210 | + cooked_font->width = w; |
|---|
| 211 | + cooked_font->height = h; |
|---|
| 212 | + FNTREFCOUNT(cooked_font) = 0; /* usage counter */ |
|---|
| 213 | + |
|---|
| 214 | + p = (unsigned char *) new_font; |
|---|
| 215 | + p += sizeof(*new_font); |
|---|
| 216 | + for (i = 0; i < op->charcount; i++) { |
|---|
| 217 | + memcpy(p, data, bpc); |
|---|
| 218 | + data += pitch*32; |
|---|
| 219 | + p += bpc; |
|---|
| 220 | + } |
|---|
| 221 | + FNTCRC(cooked_font) = crc32(0, new_font, size + sizeof(*new_font)); |
|---|
| 222 | + sti_font_convert_bytemode(sti, cooked_font); |
|---|
| 223 | + new_font = cooked_font->raw_ptr; |
|---|
| 224 | + |
|---|
| 225 | + /* check if font is already used by other console */ |
|---|
| 226 | + for (i = 0; i < MAX_NR_CONSOLES; i++) { |
|---|
| 227 | + if (font_data[i] != STI_DEF_FONT |
|---|
| 228 | + && (FNTCRC(font_data[i]) == FNTCRC(cooked_font))) { |
|---|
| 229 | + kfree(new_font); |
|---|
| 230 | + kfree(cooked_font); |
|---|
| 231 | + /* current font is the same as the new one */ |
|---|
| 232 | + if (i == unit) |
|---|
| 233 | + return 0; |
|---|
| 234 | + cooked_font = font_data[i]; |
|---|
| 235 | + new_font = cooked_font->raw_ptr; |
|---|
| 236 | + break; |
|---|
| 237 | + } |
|---|
| 238 | + } |
|---|
| 239 | + |
|---|
| 240 | + /* clear screen with old font: we now may have less rows */ |
|---|
| 241 | + vc_old_rows = vc->vc_rows; |
|---|
| 242 | + vc_old_cols = vc->vc_cols; |
|---|
| 243 | + sti_clear(sticon_sti, 0, 0, vc_old_rows, vc_old_cols, |
|---|
| 244 | + vc->vc_video_erase_char, font_data[vc->vc_num]); |
|---|
| 245 | + |
|---|
| 246 | + /* delete old font in case it is a user font */ |
|---|
| 247 | + sticon_set_def_font(unit, NULL); |
|---|
| 248 | + |
|---|
| 249 | + FNTREFCOUNT(cooked_font)++; |
|---|
| 250 | + font_data[unit] = cooked_font; |
|---|
| 251 | + |
|---|
| 252 | + vc_cols = sti_onscreen_x(sti) / cooked_font->width; |
|---|
| 253 | + vc_rows = sti_onscreen_y(sti) / cooked_font->height; |
|---|
| 254 | + vc_resize(vc, vc_cols, vc_rows); |
|---|
| 255 | + |
|---|
| 256 | + /* need to repaint screen if cols & rows are same as old font */ |
|---|
| 257 | + if (vc_cols == vc_old_cols && vc_rows == vc_old_rows) |
|---|
| 258 | + update_screen(vc); |
|---|
| 259 | + |
|---|
| 260 | + return 0; |
|---|
| 261 | +} |
|---|
| 262 | + |
|---|
| 263 | +static int sticon_font_default(struct vc_data *vc, struct console_font *op, char *name) |
|---|
| 264 | +{ |
|---|
| 265 | + return sticon_set_def_font(vc->vc_num, op); |
|---|
| 266 | +} |
|---|
| 267 | + |
|---|
| 268 | +static int sticon_font_set(struct vc_data *vc, struct console_font *font, |
|---|
| 269 | + unsigned int flags) |
|---|
| 270 | +{ |
|---|
| 271 | + return sticon_set_font(vc, font); |
|---|
| 179 | 272 | } |
|---|
| 180 | 273 | |
|---|
| 181 | 274 | static void sticon_init(struct vc_data *c, int init) |
|---|
| .. | .. |
|---|
| 184 | 277 | int vc_cols, vc_rows; |
|---|
| 185 | 278 | |
|---|
| 186 | 279 | sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0); |
|---|
| 187 | | - vc_cols = sti_onscreen_x(sti) / sti->font_width; |
|---|
| 188 | | - vc_rows = sti_onscreen_y(sti) / sti->font_height; |
|---|
| 280 | + vc_cols = sti_onscreen_x(sti) / sti->font->width; |
|---|
| 281 | + vc_rows = sti_onscreen_y(sti) / sti->font->height; |
|---|
| 189 | 282 | c->vc_can_do_color = 1; |
|---|
| 190 | 283 | |
|---|
| 191 | 284 | if (init) { |
|---|
| 192 | 285 | c->vc_cols = vc_cols; |
|---|
| 193 | 286 | c->vc_rows = vc_rows; |
|---|
| 194 | 287 | } else { |
|---|
| 195 | | - /* vc_rows = (c->vc_rows > vc_rows) ? vc_rows : c->vc_rows; */ |
|---|
| 196 | | - /* vc_cols = (c->vc_cols > vc_cols) ? vc_cols : c->vc_cols; */ |
|---|
| 197 | 288 | vc_resize(c, vc_cols, vc_rows); |
|---|
| 198 | | -/* vc_resize_con(vc_rows, vc_cols, c->vc_num); */ |
|---|
| 199 | 289 | } |
|---|
| 200 | 290 | } |
|---|
| 201 | 291 | |
|---|
| 202 | 292 | static void sticon_deinit(struct vc_data *c) |
|---|
| 203 | 293 | { |
|---|
| 294 | + int i; |
|---|
| 295 | + |
|---|
| 296 | + /* free memory used by user font */ |
|---|
| 297 | + for (i = 0; i < MAX_NR_CONSOLES; i++) |
|---|
| 298 | + sticon_set_def_font(i, NULL); |
|---|
| 204 | 299 | } |
|---|
| 205 | 300 | |
|---|
| 206 | 301 | static void sticon_clear(struct vc_data *conp, int sy, int sx, int height, |
|---|
| .. | .. |
|---|
| 209 | 304 | if (!height || !width) |
|---|
| 210 | 305 | return; |
|---|
| 211 | 306 | |
|---|
| 212 | | - sti_clear(sticon_sti, sy, sx, height, width, conp->vc_video_erase_char); |
|---|
| 307 | + sti_clear(sticon_sti, sy, sx, height, width, |
|---|
| 308 | + conp->vc_video_erase_char, font_data[conp->vc_num]); |
|---|
| 213 | 309 | } |
|---|
| 214 | 310 | |
|---|
| 215 | 311 | static int sticon_switch(struct vc_data *conp) |
|---|
| 216 | 312 | { |
|---|
| 217 | 313 | return 1; /* needs refreshing */ |
|---|
| 218 | | -} |
|---|
| 219 | | - |
|---|
| 220 | | -static int sticon_set_origin(struct vc_data *conp) |
|---|
| 221 | | -{ |
|---|
| 222 | | - return 0; |
|---|
| 223 | 314 | } |
|---|
| 224 | 315 | |
|---|
| 225 | 316 | static int sticon_blank(struct vc_data *c, int blank, int mode_switch) |
|---|
| .. | .. |
|---|
| 229 | 320 | vga_is_gfx = 0; |
|---|
| 230 | 321 | return 1; |
|---|
| 231 | 322 | } |
|---|
| 232 | | - sticon_set_origin(c); |
|---|
| 233 | | - sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK); |
|---|
| 323 | + sti_clear(sticon_sti, 0, 0, c->vc_rows, c->vc_cols, BLANK, |
|---|
| 324 | + font_data[c->vc_num]); |
|---|
| 234 | 325 | if (mode_switch) |
|---|
| 235 | 326 | vga_is_gfx = 1; |
|---|
| 236 | 327 | return 1; |
|---|
| 237 | 328 | } |
|---|
| 238 | 329 | |
|---|
| 239 | | -static u16 *sticon_screen_pos(struct vc_data *conp, int offset) |
|---|
| 240 | | -{ |
|---|
| 241 | | - int line; |
|---|
| 242 | | - unsigned long p; |
|---|
| 243 | | - |
|---|
| 244 | | - if (conp->vc_num != fg_console || !softback_lines) |
|---|
| 245 | | - return (u16 *)(conp->vc_origin + offset); |
|---|
| 246 | | - line = offset / conp->vc_size_row; |
|---|
| 247 | | - if (line >= softback_lines) |
|---|
| 248 | | - return (u16 *)(conp->vc_origin + offset - softback_lines * conp->vc_size_row); |
|---|
| 249 | | - p = softback_curr + offset; |
|---|
| 250 | | - if (p >= softback_end) |
|---|
| 251 | | - p += softback_buf - softback_end; |
|---|
| 252 | | - return (u16 *)p; |
|---|
| 253 | | -} |
|---|
| 254 | | - |
|---|
| 255 | | -static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos, |
|---|
| 256 | | - int *px, int *py) |
|---|
| 257 | | -{ |
|---|
| 258 | | - int x, y; |
|---|
| 259 | | - unsigned long ret; |
|---|
| 260 | | - if (pos >= conp->vc_origin && pos < conp->vc_scr_end) { |
|---|
| 261 | | - unsigned long offset = (pos - conp->vc_origin) / 2; |
|---|
| 262 | | - |
|---|
| 263 | | - x = offset % conp->vc_cols; |
|---|
| 264 | | - y = offset / conp->vc_cols; |
|---|
| 265 | | - if (conp->vc_num == fg_console) |
|---|
| 266 | | - y += softback_lines; |
|---|
| 267 | | - ret = pos + (conp->vc_cols - x) * 2; |
|---|
| 268 | | - } else if (conp->vc_num == fg_console && softback_lines) { |
|---|
| 269 | | - unsigned long offset = pos - softback_curr; |
|---|
| 270 | | - |
|---|
| 271 | | - if (pos < softback_curr) |
|---|
| 272 | | - offset += softback_end - softback_buf; |
|---|
| 273 | | - offset /= 2; |
|---|
| 274 | | - x = offset % conp->vc_cols; |
|---|
| 275 | | - y = offset / conp->vc_cols; |
|---|
| 276 | | - ret = pos + (conp->vc_cols - x) * 2; |
|---|
| 277 | | - if (ret == softback_end) |
|---|
| 278 | | - ret = softback_buf; |
|---|
| 279 | | - if (ret == softback_in) |
|---|
| 280 | | - ret = conp->vc_origin; |
|---|
| 281 | | - } else { |
|---|
| 282 | | - /* Should not happen */ |
|---|
| 283 | | - x = y = 0; |
|---|
| 284 | | - ret = conp->vc_origin; |
|---|
| 285 | | - } |
|---|
| 286 | | - if (px) *px = x; |
|---|
| 287 | | - if (py) *py = y; |
|---|
| 288 | | - return ret; |
|---|
| 289 | | -} |
|---|
| 290 | | - |
|---|
| 291 | | -static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, |
|---|
| 292 | | - u8 blink, u8 underline, u8 reverse, u8 italic) |
|---|
| 330 | +static u8 sticon_build_attr(struct vc_data *conp, u8 color, |
|---|
| 331 | + enum vc_intensity intens, |
|---|
| 332 | + bool blink, bool underline, bool reverse, |
|---|
| 333 | + bool italic) |
|---|
| 293 | 334 | { |
|---|
| 294 | 335 | u8 fg = color & 7; |
|---|
| 295 | 336 | u8 bg = (color & 0x70) >> 4; |
|---|
| .. | .. |
|---|
| 316 | 357 | } |
|---|
| 317 | 358 | } |
|---|
| 318 | 359 | |
|---|
| 319 | | -static void sticon_save_screen(struct vc_data *conp) |
|---|
| 320 | | -{ |
|---|
| 321 | | -} |
|---|
| 322 | | - |
|---|
| 323 | 360 | static const struct consw sti_con = { |
|---|
| 324 | 361 | .owner = THIS_MODULE, |
|---|
| 325 | 362 | .con_startup = sticon_startup, |
|---|
| .. | .. |
|---|
| 332 | 369 | .con_scroll = sticon_scroll, |
|---|
| 333 | 370 | .con_switch = sticon_switch, |
|---|
| 334 | 371 | .con_blank = sticon_blank, |
|---|
| 335 | | - .con_set_origin = sticon_set_origin, |
|---|
| 336 | | - .con_save_screen = sticon_save_screen, |
|---|
| 372 | + .con_font_set = sticon_font_set, |
|---|
| 373 | + .con_font_default = sticon_font_default, |
|---|
| 337 | 374 | .con_build_attr = sticon_build_attr, |
|---|
| 338 | 375 | .con_invert_region = sticon_invert_region, |
|---|
| 339 | | - .con_screen_pos = sticon_screen_pos, |
|---|
| 340 | | - .con_getxy = sticon_getxy, |
|---|
| 341 | 376 | }; |
|---|
| 342 | 377 | |
|---|
| 343 | 378 | |
|---|
| 344 | 379 | |
|---|
| 345 | 380 | static int __init sticonsole_init(void) |
|---|
| 346 | 381 | { |
|---|
| 347 | | - int err; |
|---|
| 382 | + int err, i; |
|---|
| 383 | + |
|---|
| 348 | 384 | /* already initialized ? */ |
|---|
| 349 | 385 | if (sticon_sti) |
|---|
| 350 | 386 | return 0; |
|---|
| .. | .. |
|---|
| 353 | 389 | if (!sticon_sti) |
|---|
| 354 | 390 | return -ENODEV; |
|---|
| 355 | 391 | |
|---|
| 356 | | - if (conswitchp == &dummy_con) { |
|---|
| 357 | | - printk(KERN_INFO "sticon: Initializing STI text console.\n"); |
|---|
| 358 | | - console_lock(); |
|---|
| 359 | | - err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, 1); |
|---|
| 360 | | - console_unlock(); |
|---|
| 361 | | - return err; |
|---|
| 362 | | - } |
|---|
| 363 | | - return 0; |
|---|
| 392 | + for (i = 0; i < MAX_NR_CONSOLES; i++) |
|---|
| 393 | + font_data[i] = STI_DEF_FONT; |
|---|
| 394 | + |
|---|
| 395 | + pr_info("sticon: Initializing STI text console.\n"); |
|---|
| 396 | + console_lock(); |
|---|
| 397 | + err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, |
|---|
| 398 | + PAGE0->mem_cons.cl_class != CL_DUPLEX); |
|---|
| 399 | + console_unlock(); |
|---|
| 400 | + |
|---|
| 401 | + return err; |
|---|
| 364 | 402 | } |
|---|
| 365 | 403 | |
|---|
| 366 | 404 | module_init(sticonsole_init); |
|---|