51 #include <linux/module.h>
52 #include <linux/kernel.h>
53 #include <linux/signal.h>
56 #include <linux/tty.h>
58 #include <linux/string.h>
72 #ifdef INCL_SISUSB_CON
74 #define sisusbcon_writew(val, addr) (*(addr) = (val))
75 #define sisusbcon_readw(addr) (*(addr))
76 #define sisusbcon_memmovew(d, s, c) memmove(d, s, c)
77 #define sisusbcon_memcpyw(d, s, c) memcpy(d, s, c)
83 static const struct consw sisusb_con;
90 sisusbcon_writew(c, s++);
118 if (sisusb->sisusb_cursor_loc == location)
121 sisusb->sisusb_cursor_loc =
location;
128 if ((location & 0x0007) == 0x0007) {
129 sisusb->bad_cursor_pos = 1;
133 }
else if (sisusb->bad_cursor_pos) {
136 sisusb->bad_cursor_pos = 0;
145 sisusb_get_sisusb(
unsigned short console)
160 sisusb_get_sisusb_lock_and_check(
unsigned short console)
172 if (!(sisusb = sisusb_get_sisusb(console)))
177 if (!sisusb_sisusb_valid(sisusb) ||
178 !sisusb->havethisconsole[console]) {
189 if (sisusb->is_gfx ||
190 sisusb->textmodedestroyed ||
199 sisusbcon_startup(
void)
217 if (!(sisusb = sisusb_get_sisusb(c->
vc_num)))
222 if (!sisusb_sisusb_valid(sisusb)) {
233 sisusb->haveconsole = 1;
235 sisusb->havethisconsole[c->
vc_num] = 1;
240 c->
vc_font.height = sisusb->current_font_height;
255 kref_get(&sisusb->
kref);
271 sisusbcon_deinit(
struct vc_data *c)
280 if (!(sisusb = sisusb_get_sisusb(c->
vc_num)))
288 sisusb->havethisconsole[c->
vc_num] = 0;
291 if (sisusb->font_backup) {
293 if (sisusb->havethisconsole[c->
vc_num])
296 if (i == MAX_NR_CONSOLES) {
297 vfree(sisusb->font_backup);
298 sisusb->font_backup =
NULL;
317 else if (intensity == 0)
321 attr = ((
attr) & 0x88) |
323 ((
attr) << 4)) & 0x77);
336 sisusbcon_invert_region(
struct vc_data *
vc,
u16 *
p,
int count)
345 u16 a = sisusbcon_readw(p);
348 (((
a) & 0x7000) >> 4) |
349 (((a) & 0x0700) << 4);
351 sisusbcon_writew(a, p++);
355 #define SISUSB_VADDR(x,y) \
356 ((u16 *)c->vc_origin + \
357 (y) * sisusb->sisusb_num_columns + \
360 #define SISUSB_HADDR(x,y) \
361 ((u16 *)(sisusb->vrambase + (c->vc_origin - sisusb->scrbuf)) + \
362 (y) * sisusb->sisusb_num_columns + \
367 sisusbcon_putc(
struct vc_data *c,
int ch,
int y,
int x)
372 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
376 if (sisusb_is_inactive(c, sisusb)) {
383 (
long)SISUSB_HADDR(x, y), 2, &written);
390 sisusbcon_putcs(
struct vc_data *c,
const unsigned short *s,
391 int count,
int y,
int x)
398 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
407 dest = SISUSB_VADDR(x, y);
409 for (i = count; i > 0; i--)
410 sisusbcon_writew(sisusbcon_readw(s++), dest++);
412 if (sisusb_is_inactive(c, sisusb)) {
418 (
long)SISUSB_HADDR(x, y), count * 2, &written);
433 if (width <= 0 || height <= 0)
436 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
445 dest = SISUSB_VADDR(x, y);
447 cols = sisusb->sisusb_num_columns;
452 if (x == 0 && width >= c->
vc_cols) {
454 sisusbcon_memsetw(dest, eattr, height * cols * 2);
458 for (i = height; i > 0; i--, dest +=
cols)
459 sisusbcon_memsetw(dest, eattr, width * 2);
463 if (sisusb_is_inactive(c, sisusb)) {
468 length = ((height *
cols) - x - (cols - width - x)) * 2;
472 (
long)SISUSB_HADDR(x, y), length, &written);
479 sisusbcon_bmove(
struct vc_data *c,
int sy,
int sx,
480 int dy,
int dx,
int height,
int width)
486 if (width <= 0 || height <= 0)
489 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
494 cols = sisusb->sisusb_num_columns;
496 if (sisusb_is_inactive(c, sisusb)) {
501 length = ((height *
cols) - dx - (cols - width - dx)) * 2;
505 (
long)SISUSB_HADDR(dx, dy), length, &written);
512 sisusbcon_switch(
struct vc_data *c)
523 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
529 if (sisusb_is_inactive(c, sisusb)) {
546 (
int)(sisusb->scrbuf + sisusb->scrbuf_size - c->
vc_origin));
553 (
long)SISUSB_HADDR(0, 0),
563 sisusbcon_save_screen(
struct vc_data *c)
572 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
577 if (sisusb_is_inactive(c, sisusb)) {
584 (
int)(sisusb->scrbuf + sisusb->scrbuf_size - c->
vc_origin));
595 sisusbcon_set_palette(
struct vc_data *c,
unsigned char *
table)
605 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
610 if (sisusb_is_inactive(c, sisusb)) {
615 for (i = j = 0; i < 16; i++) {
633 sisusbcon_blank(
struct vc_data *c,
int blank,
int mode_switch)
636 u8 sr1, cr17, pmreg, cr63;
640 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
646 sisusb->is_gfx = blank ? 1 : 0;
648 if (sisusb_is_inactive(c, sisusb)) {
665 sisusb->con_blanked = 1;
677 sisusb->con_blanked = 0;
716 sisusbcon_scrolldelta(
struct vc_data *c,
int lines)
724 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
729 if (sisusb_is_inactive(c, sisusb)) {
738 if (sisusb->con_rolled_over >
747 we = sisusb->scrbuf_size;
754 st = (c->
vc_origin - sisusb->scrbuf - ul + we) % we;
768 sisusbcon_set_start_address(sisusb, c);
780 int from, to, baseline;
782 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
787 if (sisusb_is_inactive(c, sisusb)) {
794 sisusbcon_set_start_address(sisusb, c);
799 sisusb->sisusb_cursor_size_to = -1;
830 if (sisusb->sisusb_cursor_size_from != from ||
831 sisusb->sisusb_cursor_size_to != to) {
836 sisusb->sisusb_cursor_size_from =
from;
837 sisusb->sisusb_cursor_size_to = to;
845 int t,
int b,
int dir,
int lines)
847 int cols = sisusb->sisusb_num_columns;
848 int length = ((b -
t) * cols) * 2;
863 sisusbcon_memmovew(SISUSB_VADDR(0, t),
864 SISUSB_VADDR(0, t + lines),
865 (b - t - lines) * cols * 2);
866 sisusbcon_memsetw(SISUSB_VADDR(0, b - lines), eattr,
871 sisusbcon_memmovew(SISUSB_VADDR(0, t + lines),
873 (b - t - lines) * cols * 2);
874 sisusbcon_memsetw(SISUSB_VADDR(0, t), eattr,
880 (
long)SISUSB_HADDR(0, t), length, &written);
889 sisusbcon_scroll(
struct vc_data *c,
int t,
int b,
int dir,
int lines)
895 unsigned long oldorigin;
909 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
914 if (sisusb_is_inactive(c, sisusb)) {
921 return sisusbcon_scroll_area(c, sisusb, t, b, dir, lines);
925 sisusbcon_set_start_address(sisusb, c);
939 sisusb->scrbuf + sisusb->scrbuf_size) {
940 sisusbcon_memcpyw((
u16 *)sisusb->scrbuf,
941 (
u16 *)(oldorigin + delta),
944 sisusb->con_rolled_over = oldorigin - sisusb->scrbuf;
957 if (oldorigin - delta < sisusb->scrbuf) {
958 sisusbcon_memmovew((
u16 *)(sisusb->scrbuf +
959 sisusb->scrbuf_size -
965 sisusb->scrbuf_size -
967 sisusb->con_rolled_over = 0;
986 else if (dir ==
SM_UP)
1001 sisusbcon_set_start_address(sisusb, c);
1012 sisusbcon_set_origin(
struct vc_data *c)
1021 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
1026 if (sisusb_is_inactive(c, sisusb) || sisusb->con_blanked) {
1033 sisusbcon_set_start_address(sisusb, c);
1035 sisusb->con_rolled_over = 0;
1044 sisusbcon_resize(
struct vc_data *c,
unsigned int newcols,
unsigned int newrows,
1050 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
1053 fh = sisusb->current_font_height;
1073 struct vc_data *c,
int fh,
int uplock)
1075 int font_select = 0x00,
i,
err = 0;
1087 if ((slot != 0 && slot != 2) || !fh) {
1094 sisusb->font_slot =
slot;
1102 font_select = (slot == 0) ? 0x00 : (ch512 ? 0x0e : 0x0a);
1121 for (i = 0; i <
cmapsz; i++) {
1129 for (i = 0; i <
cmapsz; i++) {
1144 for (i = 0; i <
cmapsz; i++) {
1153 for (i = 0; i <
cmapsz; i++) {
1184 if ((
set) && (ch512 != sisusb->current_font_512)) {
1191 if (d && d->
vc_sw == &sisusb_con)
1195 sisusb->current_font_512 = ch512;
1215 unsigned char ovr, vde, fsr;
1216 int rows = 0, maxscan = 0;
1223 maxscan = rows * fh - 1;
1229 vde = maxscan & 0xff;
1230 ovr = (ovr & 0xbd) |
1231 ((maxscan & 0x100) >> 7) |
1232 ((maxscan & 0x200) >> 3);
1239 fsr = (fsr & 0xe0) | (fh - 1);
1241 sisusb->current_font_height = fh;
1243 sisusb->sisusb_cursor_size_from = -1;
1244 sisusb->sisusb_cursor_size_to = -1;
1251 if (dorecalc && c) {
1259 if (vc && vc->
vc_sw == &sisusb_con) {
1286 if (font->
width != 8 || (charcount != 256 && charcount != 512))
1289 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
1298 if (sisusb->font_backup) {
1299 if (sisusb->font_backup_size < charcount) {
1300 vfree(sisusb->font_backup);
1301 sisusb->font_backup =
NULL;
1305 if (!sisusb->font_backup)
1306 sisusb->font_backup =
vmalloc(charcount * 32);
1308 if (sisusb->font_backup) {
1309 memcpy(sisusb->font_backup, font->
data, charcount * 32);
1310 sisusb->font_backup_size = charcount;
1311 sisusb->font_backup_height = font->
height;
1312 sisusb->font_backup_512 = (charcount == 512) ? 1 : 0;
1318 8192, (charcount == 512),
1329 if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->
vc_num)))
1343 if (!sisusb->font_backup) {
1349 memcpy(font->
data, sisusb->font_backup, 256 * 32);
1360 static const struct consw sisusb_con = {
1362 .con_startup = sisusbcon_startup,
1363 .con_init = sisusbcon_init,
1364 .con_deinit = sisusbcon_deinit,
1365 .con_clear = sisusbcon_clear,
1366 .con_putc = sisusbcon_putc,
1367 .con_putcs = sisusbcon_putcs,
1368 .con_cursor = sisusbcon_cursor,
1369 .con_scroll = sisusbcon_scroll,
1370 .con_bmove = sisusbcon_bmove,
1371 .con_switch = sisusbcon_switch,
1372 .con_blank = sisusbcon_blank,
1373 .con_font_set = sisusbcon_font_set,
1374 .con_font_get = sisusbcon_font_get,
1375 .con_set_palette = sisusbcon_set_palette,
1376 .con_scrolldelta = sisusbcon_scrolldelta,
1377 .con_build_attr = sisusbcon_build_attr,
1378 .con_invert_region = sisusbcon_invert_region,
1379 .con_set_origin = sisusbcon_set_origin,
1380 .con_save_screen = sisusbcon_save_screen,
1381 .con_resize = sisusbcon_resize,
1386 static const char *sisusbdummycon_startup(
void)
1388 return "SISUSBVGADUMMY";
1391 static void sisusbdummycon_init(
struct vc_data *vc,
int init)
1401 static int sisusbdummycon_dummy(
void)
1406 #define SISUSBCONDUMMY (void *)sisusbdummycon_dummy
1408 static const struct consw sisusb_dummy_con = {
1410 .con_startup = sisusbdummycon_startup,
1411 .con_init = sisusbdummycon_init,
1412 .con_deinit = SISUSBCONDUMMY,
1413 .con_clear = SISUSBCONDUMMY,
1414 .con_putc = SISUSBCONDUMMY,
1415 .con_putcs = SISUSBCONDUMMY,
1416 .con_cursor = SISUSBCONDUMMY,
1417 .con_scroll = SISUSBCONDUMMY,
1418 .con_bmove = SISUSBCONDUMMY,
1419 .con_switch = SISUSBCONDUMMY,
1420 .con_blank = SISUSBCONDUMMY,
1421 .con_font_set = SISUSBCONDUMMY,
1422 .con_font_get = SISUSBCONDUMMY,
1423 .con_font_default = SISUSBCONDUMMY,
1424 .con_font_copy = SISUSBCONDUMMY,
1425 .con_set_palette = SISUSBCONDUMMY,
1426 .con_scrolldelta = SISUSBCONDUMMY,
1437 if (sisusb->haveconsole || !sisusb->SiS_Pr) {
1442 sisusb->con_first =
first;
1443 sisusb->con_last = last;
1446 first > MAX_NR_CONSOLES ||
1447 last > MAX_NR_CONSOLES) {
1453 if (!sisusb->
gfxinit || first < 1 || last < 1) {
1458 sisusb->sisusb_cursor_loc = -1;
1459 sisusb->sisusb_cursor_size_from = -1;
1460 sisusb->sisusb_cursor_size_to = -1;
1470 sisusb_initialize(sisusb);
1472 for (i = first - 1; i <= last - 1; i++) {
1474 mysisusbs[
i] = sisusb;
1478 sisusb->sisusb_num_columns = 80;
1481 sisusb->scrbuf_size = 32 * 1024;
1484 if (!(sisusb->scrbuf = (
unsigned long)
vmalloc(sisusb->scrbuf_size))) {
1496 sisusb->haveconsole = 1;
1498 for (i = first - 1; i <= last - 1; i++)
1499 mysisusbs[i] =
NULL;
1536 if (sisusb->haveconsole) {
1538 if (sisusb->havethisconsole[i])
1543 sisusb->haveconsole = 0;
1546 vfree((
void *)sisusb->scrbuf);
1549 vfree(sisusb->font_backup);
1550 sisusb->font_backup =
NULL;
1558 mysisusbs[i] =
NULL;