/*
 * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles
 *
 * VGA text mode console part
 *
 * Copyright (C) 2005 by Thomas Winischhofer, Vienna, Austria
 *
 * If distributed as part of the Linux kernel, this code is licensed under the
 * terms of the GPL v2.
 *
 * Otherwise, the following license terms apply:
 *
 * * Redistribution and use in source and binary forms, with or without
 * * modification, are permitted provided that the following conditions
 * * are met:
 * * 1) Redistributions of source code must retain the above copyright
 * *    notice, this list of conditions and the following disclaimer.
 * * 2) Redistributions in binary form must reproduce the above copyright
 * *    notice, this list of conditions and the following disclaimer in the
 * *    documentation and/or other materials provided with the distribution.
 * * 3) The name of the author may not be used to endorse or promote products
 * *    derived from this software without specific psisusbr written permission.
 * *
 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Author: Thomas Winischhofer <thomas@winischhofer.net>
 *
 * Portions based on vgacon.c which are
 *	Created 28 Sep 1997 by Geert Uytterhoeven
 *      Rewritten by Martin Mares <mj@ucw.cz>, July 1998
 *      based on code Copyright (C) 1991, 1992  Linus Torvalds
 *			    1995  Jay Estabrook
 *
 * A note on using in_atomic() in here: We can't handle console
 * calls from non-schedulable context due to our USB-dependend
 * nature. For now, this driver just ignores any calls if it
 * detects this state.
 *
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/string.h>
#include <linux/kd.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>
#include <linux/spinlock.h>
#include <linux/kref.h>
#include <linux/smp_lock.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>

#include "sisusb.h"

#ifdef INCL_SISUSB_CON
extern int sisusb_setreg(struct sisusb_usb_data *, int, u8);
extern int sisusb_getreg(struct sisusb_usb_data *, int, u8 *);
extern int sisusb_setidxreg(struct sisusb_usb_data *, int, u8, u8);
extern int sisusb_getidxreg(struct sisusb_usb_data *, int, u8, u8 *);
extern int sisusb_setidxregor(struct sisusb_usb_data *, int, u8, u8);
extern int sisusb_setidxregand(struct sisusb_usb_data *, int, u8, u8);
extern int sisusb_setidxregandor(struct sisusb_usb_data *, int, u8, u8, u8);

extern int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data);
extern int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data);
extern int sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data);
extern int sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data);
extern int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src,
			u32 dest, int length, size_t *bytes_written);

extern void sisusb_delete(struct kref *kref);
extern int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init);

extern int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo);

#define sisusbcon_writew(val, addr)	(*(addr) = (val))
#define sisusbcon_readw(addr)		(*(addr))
#define sisusbcon_memmovew(d, s, c)	memmove(d, s, c)
#define sisusbcon_memcpyw(d, s, c)	memcpy(d, s, c)

/* vc_data -> sisusb conversion table */
static struct sisusb_usb_data *mysisusbs[MAX_NR_CONSOLES];

/* Forward declaration */
static const struct consw sisusb_con;

extern struct semaphore disconnect_sem;

static inline void
sisusbcon_memsetw(u16 *s, u16 c, unsigned int count)
{
	count /= 2;
	while (count--)
		sisusbcon_writew(c, s++);
}

static inline void
sisusb_initialize(struct sisusb_usb_data *sisusb)
{
	/* Reset cursor and start address */
	if (sisusb_setidxreg(sisusb, SISCR, 0x0c, 0x00))
		return;
	if (sisusb_setidxreg(sisusb, SISCR, 0x0d, 0x00))
		return;
	if (sisusb_setidxreg(sisusb, SISCR, 0x0e, 0x00))
		return;
	sisusb_setidxreg(sisusb, SISCR, 0x0f, 0x00);
}

static inline void
sisusbcon_set_start_address(struct sisusb_usb_data *sisusb, struct vc_data *c)
{
	sisusb->cur_start_addr = (c->vc_visible_origin - sisusb->scrbuf) / 2;

	sisusb_setidxreg(sisusb, SISCR, 0x0c, (sisusb->cur_start_addr >> 8));
	sisusb_setidxreg(sisusb, SISCR, 0x0d, (sisusb->cur_start_addr & 0xff));
}

void
sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location)
{
	if (sisusb->sisusb_cursor_loc == location)
		return;

	sisusb->sisusb_cursor_loc = location;

	/* Hardware bug: Text cursor appears twice or not at all
	 * at some positions. Work around it with the cursor skew
	 * bits.
	 */

	if ((location & 0x0007) == 0x0007) {
		sisusb->bad_cursor_pos = 1;
		location--;
		if (sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0x1f, 0x20))
			return;
	} else if (sisusb->bad_cursor_pos) {
		if (sisusb_setidxregand(sisusb, SISCR, 0x0b, 0x1f))
			return;
		sisusb->bad_cursor_pos = 0;
	}

	if (sisusb_setidxreg(sisusb, SISCR, 0x0e, (location >> 8)))
		return;
	sisusb_setidxreg(sisusb, SISCR, 0x0f, (location & 0xff));
}

static inline struct sisusb_usb_data *
sisusb_get_sisusb(unsigned short console)
{
	return mysisusbs[console];
}

static inline int
sisusb_sisusb_valid(struct sisusb_usb_data *sisusb)
{
	if (!sisusb->present || !sisusb->ready || !sisusb->sisusb_dev)
		return 0;

	return 1;
}

static struct sisusb_usb_data *
sisusb_get_sisusb_lock_and_check(unsigned short console)
{
	struct sisusb_usb_data *sisusb;

	/* We can't handle console calls in non-schedulable
	 * context due to our locks and the USB transport.
	 * So we simply ignore them. This should only affect
	 * some calls to printk.
	 */
	if (in_atomic())
		return NULL;

	if (!(sisusb = sisusb_get_sisusb(console)))
		return NULL;

	down(&sisusb->lock);

	if (!sisusb_sisusb_valid(sisusb) ||
	    !sisusb->havethisconsole[console]) {
		up(&sisusb->lock);
		return NULL;
	}

	return sisusb;
}

static int
sisusb_is_inactive(struct vc_data *c, struct sisusb_usb_data *sisusb)
{
	if (sisusb->is_gfx ||
	    sisusb->textmodedestroyed ||
	    c->vc_mode != KD_TEXT)
		return 1;

	return 0;
}

/* con_startup console interface routine */
static const char *
sisusbcon_startup(void)
{
	return "SISUSBCON";
}

/* con_init console interface routine */
static void
sisusbcon_init(struct vc_data *c, int init)
{
	struct sisusb_usb_data *sisusb;
	int cols, rows;

	/* This is called by take_over_console(),
	 * ie by us/under our control. It is
	 * only called after text mode and fonts
	 * are set up/restored.
	 */

	down(&disconnect_sem);

	if (!(sisusb = sisusb_get_sisusb(c->vc_num))) {
		up(&disconnect_sem);
		return;
	}

	down(&sisusb->lock);

	if (!sisusb_sisusb_valid(sisusb)) {
		up(&sisusb->lock);
		up(&disconnect_sem);
		return;
	}

	c->vc_can_do_color = 1;

	c->vc_complement_mask = 0x7700;

	c->vc_hi_font_mask = sisusb->current_font_512 ? 0x0800 : 0;

	sisusb->haveconsole = 1;

	sisusb->havethisconsole[c->vc_num] = 1;

	/* We only support 640x400 */
	c->vc_scan_lines = 400;

	c->vc_font.height = sisusb->current_font_height;

	/* We only support width = 8 */
	cols = 80;
	rows = c->vc_scan_lines / c->vc_font.height;

	/* Increment usage count for our sisusb.
	 * Doing so saves us from upping/downing
	 * the disconnect semaphore; we can't
	 * lose our sisusb until this is undone
	 * in con_deinit. For all other console
	 * interface functions, it suffices to
	 * use sisusb->lock and do a quick check
	 * of sisusb for device disconnection.
	 */
	kref_get(&sisusb->kref);

	if (!*c->vc_uni_pagedir_loc)
		con_set_default_unimap(c);

	up(&sisusb->lock);

	up(&disconnect_sem);

	if (init) {
		c->vc_cols = cols;
		c->vc_rows = rows;
	} else
		vc_resize(c, cols, rows);
}

/* con_deinit console interface routine */
static void
sisusbcon_deinit(struct vc_data *c)
{
	struct sisusb_usb_data *sisusb;
	int i;

	/* This is called by take_over_console()
	 * and others, ie not under our control.
	 */

	down(&disconnect_sem);

	if (!(sisusb = sisusb_get_sisusb(c->vc_num))) {
		up(&disconnect_sem);
		return;
	}

	down(&sisusb->lock);

	/* Clear ourselves in mysisusbs */
	mysisusbs[c->vc_num] = NULL;

	sisusb->havethisconsole[c->vc_num] = 0;

	/* Free our font buffer if all consoles are gone */
	if (sisusb->font_backup) {
		for(i = 0; i < MAX_NR_CONSOLES; i++) {
			if (sisusb->havethisconsole[c->vc_num])
				break;
		}
		if (i == MAX_NR_CONSOLES) {
			vfree(sisusb->font_backup);
			sisusb->font_backup = NULL;
		}
	}

	up(&sisusb->lock);

	/* decrement the usage count on our sisusb */
	kref_put(&sisusb->kref, sisusb_delete);

	up(&disconnect_sem);
}

/* interface routine */
static u8
sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity,
			    u8 blink, u8 underline, u8 reverse)
{
	u8 attr = color;

	if (underline)
		attr = (attr & 0xf0) | c->vc_ulcolor;
	else if (intensity == 0)
		attr = (attr & 0xf0) | c->vc_halfcolor;

	if (reverse)
		attr = ((attr) & 0x88) |
		       ((((attr) >> 4) |
		       ((attr) << 4)) & 0x77);

	if (blink)
		attr ^= 0x80;

	if (intensity == 2)
		attr ^= 0x08;

	return attr;
}

/* Interface routine */
static void
sisusbcon_invert_region(struct vc_data *vc, u16 *p, int count)
{
	/* Invert a region. This is called with a pointer
	 * to the console's internal screen buffer. So we
	 * simply do the inversion there and rely on
	 * a call to putc(s) to update the real screen.
	 */

	while (count--) {
		u16 a = sisusbcon_readw(p);

		a = ((a) & 0x88ff)        |
		    (((a) & 0x7000) >> 4) |
		    (((a) & 0x0700) << 4);

		sisusbcon_writew(a, p++);
	}
}

#define SISUSB_VADDR(x,y) \
	((u16 *)c->vc_origin + \
	(y) * sisusb->sisusb_num_columns + \
	(x))

#define SISUSB_HADDR(x,y) \
	((u16 *)(sisusb->vrambase + (c->vc_origin - sisusb->scrbuf)) + \
	(y) * sisusb->sisusb_num_columns + \
	(x))

/* Interface routine */
static void
sisusbcon_putc(struct vc_data *c, int ch, int y, int x)
{
	struct sisusb_usb_data *sisusb;
	ssize_t written;

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return;

	/* sisusb->lock is down */

	/* Don't need to put the character into buffer ourselves,
	 * because the vt does this BEFORE calling us.
	 */
#if 0
	sisusbcon_writew(ch, SISUSB_VADDR(x, y));
#endif

	if (sisusb_is_inactive(c, sisusb)) {
		up(&sisusb->lock);
		return;
	}


	sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y),
				(u32)SISUSB_HADDR(x, y), 2, &written);

	up(&sisusb->lock);
}

/* Interface routine */
static void
sisusbcon_putcs(struct vc_data *c, const unsigned short *s,
		         int count, int y, int x)
{
	struct sisusb_usb_data *sisusb;
	ssize_t written;
	u16 *dest;
	int i;

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return;

	/* sisusb->lock is down */

	/* Need to put the characters into the buffer ourselves,
	 * because the vt does this AFTER calling us.
	 */

	dest = SISUSB_VADDR(x, y);

	for (i = count; i > 0; i--)
		sisusbcon_writew(sisusbcon_readw(s++), dest++);

	if (sisusb_is_inactive(c, sisusb)) {
		up(&sisusb->lock);
		return;
	}

	sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y),
				(u32)SISUSB_HADDR(x, y), count * 2, &written);

	up(&sisusb->lock);
}

/* Interface routine */
static void
sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width)
{
	struct sisusb_usb_data *sisusb;
	u16 eattr = c->vc_video_erase_char;
	ssize_t written;
	int i, length, cols;
	u16 *dest;

	if (width <= 0 || height <= 0)
		return;

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return;

	/* sisusb->lock is down */

	/* Need to clear buffer ourselves, because the vt does
	 * this AFTER calling us.
	 */

	dest = SISUSB_VADDR(x, y);

	cols = sisusb->sisusb_num_columns;

	if (width > cols)
		width = cols;

	if (x == 0 && width >= c->vc_cols) {

		sisusbcon_memsetw(dest, eattr, height * cols * 2);

	} else {

		for (i = height; i > 0; i--, dest += cols)
			sisusbcon_memsetw(dest, eattr, width * 2);

	}

	if (sisusb_is_inactive(c, sisusb)) {
		up(&sisusb->lock);
		return;
	}

	length = ((height * cols) - x - (cols - width - x)) * 2;


	sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y),
				(u32)SISUSB_HADDR(x, y), length, &written);

	up(&sisusb->lock);
}

/* Interface routine */
static void
sisusbcon_bmove(struct vc_data *c, int sy, int sx,
			 int dy, int dx, int height, int width)
{
	struct sisusb_usb_data *sisusb;
	ssize_t written;
	int cols, length;
#if 0
	u16 *src, *dest;
	int i;
#endif

	if (width <= 0 || height <= 0)
		return;

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return;

	/* sisusb->lock is down */

	cols = sisusb->sisusb_num_columns;

	/* Don't need to move data outselves, because
	 * vt does this BEFORE calling us.
	 * This is only used by vt's insert/deletechar.
	 */
#if 0
	if (sx == 0 && dx == 0 && width >= c->vc_cols && width <= cols) {

		sisusbcon_memmovew(SISUSB_VADDR(0, dy), SISUSB_VADDR(0, sy),
					height * width * 2);

	} else if (dy < sy || (dy == sy && dx < sx)) {

		src  = SISUSB_VADDR(sx, sy);
		dest = SISUSB_VADDR(dx, dy);

		for (i = height; i > 0; i--) {
			sisusbcon_memmovew(dest, src, width * 2);
			src  += cols;
			dest += cols;
		}

	} else {

		src  = SISUSB_VADDR(sx, sy + height - 1);
		dest = SISUSB_VADDR(dx, dy + height - 1);

		for (i = height; i > 0; i--) {
			sisusbcon_memmovew(dest, src, width * 2);
			src  -= cols;
			dest -= cols;
		}

	}
#endif

	if (sisusb_is_inactive(c, sisusb)) {
		up(&sisusb->lock);
		return;
	}

	length = ((height * cols) - dx - (cols - width - dx)) * 2;


	sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(dx, dy),
				(u32)SISUSB_HADDR(dx, dy), length, &written);

	up(&sisusb->lock);
}

/* interface routine */
static int
sisusbcon_switch(struct vc_data *c)
{
	struct sisusb_usb_data *sisusb;
	ssize_t written;
	int length;

	/* Returnvalue 0 means we have fully restored screen,
	 *	and vt doesn't need to call do_update_region().
	 * Returnvalue != 0 naturally means the opposite.
	 */

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return 0;

	/* sisusb->lock is down */

	/* Don't write to screen if in gfx mode */
	if (sisusb_is_inactive(c, sisusb)) {
		up(&sisusb->lock);
		return 0;
	}

	/* That really should not happen. It would mean we are
	 * being called while the vc is using its private buffer
	 * as origin.
	 */
	if (c->vc_origin == (unsigned long)c->vc_screenbuf) {
		up(&sisusb->lock);
		printk(KERN_DEBUG "sisusb: ASSERT ORIGIN != SCREENBUF!\n");
		return 0;
	}

	/* Check that we don't copy too much */
	length = min((int)c->vc_screenbuf_size,
			(int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin));

	/* Restore the screen contents */
	sisusbcon_memcpyw((u16 *)c->vc_origin, (u16 *)c->vc_screenbuf,
								length);

	sisusb_copy_memory(sisusb, (unsigned char *)c->vc_origin,
				(u32)SISUSB_HADDR(0, 0),
				length, &written);

	up(&sisusb->lock);

	return 0;
}

/* interface routine */
static void
sisusbcon_save_screen(struct vc_data *c)
{
	struct sisusb_usb_data *sisusb;
	int length;

	/* Save the current screen contents to vc's private
	 * buffer.
	 */

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return;

	/* sisusb->lock is down */

	if (sisusb_is_inactive(c, sisusb)) {
		up(&sisusb->lock);
		return;
	}

	/* Check that we don't copy too much */
	length = min((int)c->vc_screenbuf_size,
			(int)(sisusb->scrbuf + sisusb->scrbuf_size - c->vc_origin));

	/* Save the screen contents to vc's private buffer */
	sisusbcon_memcpyw((u16 *)c->vc_screenbuf, (u16 *)c->vc_origin,
								length);

	up(&sisusb->lock);
}

/* interface routine */
static int
sisusbcon_set_palette(struct vc_data *c, unsigned char *table)
{
	struct sisusb_usb_data *sisusb;
	int i, j;

	/* Return value not used by vt */

	if (!CON_IS_VISIBLE(c))
		return -EINVAL;

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return -EINVAL;

	/* sisusb->lock is down */

	if (sisusb_is_inactive(c, sisusb)) {
		up(&sisusb->lock);
		return -EINVAL;
	}

	for (i = j = 0; i < 16; i++) {
		if (sisusb_setreg(sisusb, SISCOLIDX, table[i]))
			break;
		if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2))
			break;
		if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2))
			break;
		if (sisusb_setreg(sisusb, SISCOLDATA, c->vc_palette[j++] >> 2))
			break;
	}

	up(&sisusb->lock);

	return 0;
}

/* interface routine */
static int
sisusbcon_blank(struct vc_data *c, int blank, int mode_switch)
{
	struct sisusb_usb_data *sisusb;
	u8 sr1, cr17, pmreg, cr63;
	ssize_t written;
	int ret = 0;

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return 0;

	/* sisusb->lock is down */

	if (mode_switch)
		sisusb->is_gfx = blank ? 1 : 0;

	if (sisusb_is_inactive(c, sisusb)) {
		up(&sisusb->lock);
		return 0;
	}

	switch (blank) {

	case 1:		/* Normal blanking: Clear screen */
	case -1:
		sisusbcon_memsetw((u16 *)c->vc_origin,
				c->vc_video_erase_char,
				c->vc_screenbuf_size);
		sisusb_copy_memory(sisusb,
				(unsigned char *)c->vc_origin,
				(u32)(sisusb->vrambase +
					(c->vc_origin - sisusb->scrbuf)),
				c->vc_screenbuf_size, &written);
		sisusb->con_blanked = 1;
		ret = 1;
		break;

	default:	/* VESA blanking */
		switch (blank) {
		case 0: /* Unblank */
			sr1   = 0x00;
			cr17  = 0x80;
			pmreg = 0x00;
			cr63  = 0x00;
			ret = 1;
			sisusb->con_blanked = 0;
			break;
		case VESA_VSYNC_SUSPEND + 1:
			sr1   = 0x20;
			cr17  = 0x80;
			pmreg = 0x80;
			cr63  = 0x40;
			break;
		case VESA_HSYNC_SUSPEND + 1:
			sr1   = 0x20;
			cr17  = 0x80;
			pmreg = 0x40;
			cr63  = 0x40;
			break;
		case VESA_POWERDOWN + 1:
			sr1   = 0x20;
			cr17  = 0x00;
			pmreg = 0xc0;
			cr63  = 0x40;
			break;
		default:
			up(&sisusb->lock);
			return -EINVAL;
		}

		sisusb_setidxregandor(sisusb, SISSR, 0x01, ~0x20, sr1);
		sisusb_setidxregandor(sisusb, SISCR, 0x17, 0x7f, cr17);
		sisusb_setidxregandor(sisusb, SISSR, 0x1f, 0x3f, pmreg);
		sisusb_setidxregandor(sisusb, SISCR, 0x63, 0xbf, cr63);

	}

	up(&sisusb->lock);

	return ret;
}

/* interface routine */
static int
sisusbcon_scrolldelta(struct vc_data *c, int lines)
{
	struct sisusb_usb_data *sisusb;
	int margin = c->vc_size_row * 4;
	int ul, we, p, st;

	/* The return value does not seem to be used */

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return 0;

	/* sisusb->lock is down */

	if (sisusb_is_inactive(c, sisusb)) {
		up(&sisusb->lock);
		return 0;
	}

	if (!lines)		/* Turn scrollback off */
		c->vc_visible_origin = c->vc_origin;
	else {

		if (sisusb->con_rolled_over >
				(c->vc_scr_end - sisusb->scrbuf) + margin) {

			ul = c->vc_scr_end - sisusb->scrbuf;
			we = sisusb->con_rolled_over + c->vc_size_row;

		} else {

			ul = 0;
			we = sisusb->scrbuf_size;

		}

		p = (c->vc_visible_origin - sisusb->scrbuf - ul + we) % we +
				lines * c->vc_size_row;

		st = (c->vc_origin - sisusb->scrbuf - ul + we) % we;

		if (st < 2 * margin)
			margin = 0;

		if (p < margin)
			p = 0;

		if (p > st - margin)
			p = st;

		c->vc_visible_origin = sisusb->scrbuf + (p + ul) % we;
	}

	sisusbcon_set_start_address(sisusb, c);

	up(&sisusb->lock);

	return 1;
}

/* Interface routine */
static void
sisusbcon_cursor(struct vc_data *c, int mode)
{
	struct sisusb_usb_data *sisusb;
	int from, to, baseline;

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return;

	/* sisusb->lock is down */

	if (sisusb_is_inactive(c, sisusb)) {
		up(&sisusb->lock);
		return;
	}

	if (c->vc_origin != c->vc_visible_origin) {
		c->vc_visible_origin = c->vc_origin;
		sisusbcon_set_start_address(sisusb, c);
	}

	if (mode == CM_ERASE) {
		sisusb_setidxregor(sisusb, SISCR, 0x0a, 0x20);
		sisusb->sisusb_cursor_size_to = -1;
		up(&sisusb->lock);
		return;
	}

	sisusb_set_cursor(sisusb, (c->vc_pos - sisusb->scrbuf) / 2);

	baseline = c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2);

	switch (c->vc_cursor_type & 0x0f) {
		case CUR_BLOCK:		from = 1;
					to   = c->vc_font.height;
					break;
		case CUR_TWO_THIRDS:	from = c->vc_font.height / 3;
					to   = baseline;
					break;
		case CUR_LOWER_HALF:	from = c->vc_font.height / 2;
					to   = baseline;
					break;
		case CUR_LOWER_THIRD:	from = (c->vc_font.height * 2) / 3;
					to   = baseline;
					break;
		case CUR_NONE:		from = 31;
					to = 30;
					break;
		default:
		case CUR_UNDERLINE:	from = baseline - 1;
					to   = baseline;
					break;
	}

	if (sisusb->sisusb_cursor_size_from != from ||
	    sisusb->sisusb_cursor_size_to != to) {

		sisusb_setidxreg(sisusb, SISCR, 0x0a, from);
		sisusb_setidxregandor(sisusb, SISCR, 0x0b, 0xe0, to);

		sisusb->sisusb_cursor_size_from = from;
		sisusb->sisusb_cursor_size_to   = to;
	}

	up(&sisusb->lock);
}

static int
sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb,
					int t, int b, int dir, int lines)
{
	int cols = sisusb->sisusb_num_columns;
	int length = ((b - t) * cols) * 2;
	u16 eattr = c->vc_video_erase_char;
	ssize_t written;

	/* sisusb->lock is down */

	/* Scroll an area which does not match the
	 * visible screen's dimensions. This needs
	 * to be done separately, as it does not
	 * use hardware panning.
	 */

	switch (dir) {

		case SM_UP:
			sisusbcon_memmovew(SISUSB_VADDR(0, t),
					   SISUSB_VADDR(0, t + lines),
					   (b - t - lines) * cols * 2);
			sisusbcon_memsetw(SISUSB_VADDR(0, b - lines), eattr,
					  lines * cols * 2);
			break;

		case SM_DOWN:
			sisusbcon_memmovew(SISUSB_VADDR(0, t + lines),
					   SISUSB_VADDR(0, t),
					   (b - t - lines) * cols * 2);
			sisusbcon_memsetw(SISUSB_VADDR(0, t), eattr,
					  lines * cols * 2);
			break;
	}

	sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t),
				(u32)SISUSB_HADDR(0, t), length, &written);

	up(&sisusb->lock);

	return 1;
}

/* Interface routine */
static int
sisusbcon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
{
	struct sisusb_usb_data *sisusb;
	u16 eattr = c->vc_video_erase_char;
	ssize_t written;
	int copyall = 0;
	unsigned long oldorigin;
	unsigned int delta = lines * c->vc_size_row;
	u32 originoffset;

	/* Returning != 0 means we have done the scrolling successfully.
	 * Returning 0 makes vt do the scrolling on its own.
	 * Note that con_scroll is only called if the console is
	 * visible. In that case, the origin should be our buffer,
	 * not the vt's private one.
	 */

	if (!lines)
		return 1;

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return 0;

	/* sisusb->lock is down */

	if (sisusb_is_inactive(c, sisusb)) {
		up(&sisusb->lock);
		return 0;
	}

	/* Special case */
	if (t || b != c->vc_rows)
		return sisusbcon_scroll_area(c, sisusb, t, b, dir, lines);

	if (c->vc_origin != c->vc_visible_origin) {
		c->vc_visible_origin = c->vc_origin;
		sisusbcon_set_start_address(sisusb, c);
	}

	/* limit amount to maximum realistic size */
	if (lines > c->vc_rows)
		lines = c->vc_rows;

	oldorigin = c->vc_origin;

	switch (dir) {

	case SM_UP:

		if (c->vc_scr_end + delta >=
				sisusb->scrbuf + sisusb->scrbuf_size) {
			sisusbcon_memcpyw((u16 *)sisusb->scrbuf,
					  (u16 *)(oldorigin + delta),
					  c->vc_screenbuf_size - delta);
			c->vc_origin = sisusb->scrbuf;
			sisusb->con_rolled_over = oldorigin - sisusb->scrbuf;
			copyall = 1;
		} else
			c->vc_origin += delta;

		sisusbcon_memsetw(
			(u16 *)(c->vc_origin + c->vc_screenbuf_size - delta),
					eattr, delta);

		break;

	case SM_DOWN:

		if (oldorigin - delta < sisusb->scrbuf) {
			sisusbcon_memmovew((u16 *)(sisusb->scrbuf +
							sisusb->scrbuf_size -
							c->vc_screenbuf_size +
							delta),
					   (u16 *)oldorigin,
					   c->vc_screenbuf_size - delta);
			c->vc_origin = sisusb->scrbuf +
					sisusb->scrbuf_size -
					c->vc_screenbuf_size;
			sisusb->con_rolled_over = 0;
			copyall = 1;
		} else
			c->vc_origin -= delta;

		c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;

		scr_memsetw((u16 *)(c->vc_origin), eattr, delta);

		break;
	}

	originoffset = (u32)(c->vc_origin - sisusb->scrbuf);

	if (copyall)
		sisusb_copy_memory(sisusb,
			(char *)c->vc_origin,
			(u32)(sisusb->vrambase + originoffset),
			c->vc_screenbuf_size, &written);
	else if (dir == SM_UP)
		sisusb_copy_memory(sisusb,
			(char *)c->vc_origin + c->vc_screenbuf_size - delta,
			(u32)sisusb->vrambase + originoffset +
					c->vc_screenbuf_size - delta,
			delta, &written);
	else
		sisusb_copy_memory(sisusb,
			(char *)c->vc_origin,
			(u32)(sisusb->vrambase + originoffset),
			delta, &written);

	c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
	c->vc_visible_origin = c->vc_origin;

	sisusbcon_set_start_address(sisusb, c);

	c->vc_pos = c->vc_pos - oldorigin + c->vc_origin;

	up(&sisusb->lock);

	return 1;
}

/* Interface routine */
static int
sisusbcon_set_origin(struct vc_data *c)
{
	struct sisusb_usb_data *sisusb;

	/* Returning != 0 means we were successful.
	 * Returning 0 will vt make to use its own
	 *	screenbuffer as the origin.
	 */

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return 0;

	/* sisusb->lock is down */

	if (sisusb_is_inactive(c, sisusb) || sisusb->con_blanked) {
		up(&sisusb->lock);
		return 0;
	}

	c->vc_origin = c->vc_visible_origin = sisusb->scrbuf;

	sisusbcon_set_start_address(sisusb, c);

	sisusb->con_rolled_over = 0;

	up(&sisusb->lock);

	return 1;
}

/* Interface routine */
static int
sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows)
{
	struct sisusb_usb_data *sisusb;
	int fh;

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return -ENODEV;

	fh = sisusb->current_font_height;

	up(&sisusb->lock);

	/* We are quite unflexible as regards resizing. The vt code
	 * handles sizes where the line length isn't equal the pitch
	 * quite badly. As regards the rows, our panning tricks only
	 * work well if the number of rows equals the visible number
	 * of rows.
	 */

	if (newcols != 80 || c->vc_scan_lines / fh != newrows)
		return -EINVAL;

	return 0;
}

int
sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot,
			u8 *arg, int cmapsz, int ch512, int dorecalc,
			struct vc_data *c, int fh, int uplock)
{
	int font_select = 0x00, i, err = 0;
	u32 offset = 0;
	u8 dummy;

	/* sisusb->lock is down */

	/*
	 * The default font is kept in slot 0.
	 * A user font is loaded in slot 2 (256 ch)
	 * or 2+3 (512 ch).
	 */

	if ((slot != 0 && slot != 2) || !fh) {
		if (uplock)
			up(&sisusb->lock);
		return -EINVAL;
	}

	if (set)
		sisusb->font_slot = slot;

	/* Default font is always 256 */
	if (slot == 0)
		ch512 = 0;
	else
		offset = 4 * cmapsz;

	font_select = (slot == 0) ? 0x00 : (ch512 ? 0x0e : 0x0a);

	err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x01); /* Reset */
	err |= sisusb_setidxreg(sisusb, SISSR, 0x02, 0x04); /* Write to plane 2 */
	err |= sisusb_setidxreg(sisusb, SISSR, 0x04, 0x07); /* Memory mode a0-bf */
	err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x03); /* Reset */

	if (err)
		goto font_op_error;

	err |= sisusb_setidxreg(sisusb, SISGR, 0x04, 0x03); /* Select plane read 2 */
	err |= sisusb_setidxreg(sisusb, SISGR, 0x05, 0x00); /* Disable odd/even */
	err |= sisusb_setidxreg(sisusb, SISGR, 0x06, 0x00); /* Address range a0-bf */

	if (err)
		goto font_op_error;

	if (arg) {
		if (set)
			for (i = 0; i < cmapsz; i++) {
				err |= sisusb_writeb(sisusb,
					sisusb->vrambase + offset + i,
					arg[i]);
				if (err)
					break;
			}
		else
			for (i = 0; i < cmapsz; i++) {
				err |= sisusb_readb(sisusb,
					sisusb->vrambase + offset + i,
					&arg[i]);
				if (err)
					break;
			}

		/*
		 * In 512-character mode, the character map is not contiguous if
		 * we want to remain EGA compatible -- which we do
		 */

		if (ch512) {
			if (set)
				for (i = 0; i < cmapsz; i++) {
					err |= sisusb_writeb(sisusb,
						sisusb->vrambase + offset +
							(2 * cmapsz) + i,
						arg[cmapsz + i]);
					if (err)
						break;
				}
			else
				for (i = 0; i < cmapsz; i++) {
					err |= sisusb_readb(sisusb,
						sisusb->vrambase + offset +
							(2 * cmapsz) + i,
						&arg[cmapsz + i]);
					if (err)
						break;
				}
		}
	}

	if (err)
		goto font_op_error;

	err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x01); /* Reset */
	err |= sisusb_setidxreg(sisusb, SISSR, 0x02, 0x03); /* Write to planes 0+1 */
	err |= sisusb_setidxreg(sisusb, SISSR, 0x04, 0x03); /* Memory mode a0-bf */
	if (set)
		sisusb_setidxreg(sisusb, SISSR, 0x03, font_select);
	err |= sisusb_setidxreg(sisusb, SISSR, 0x00, 0x03); /* Reset end */

	if (err)
		goto font_op_error;

	err |= sisusb_setidxreg(sisusb, SISGR, 0x04, 0x00); /* Select plane read 0 */
	err |= sisusb_setidxreg(sisusb, SISGR, 0x05, 0x10); /* Enable odd/even */
	err |= sisusb_setidxreg(sisusb, SISGR, 0x06, 0x06); /* Address range b8-bf */

	if (err)
		goto font_op_error;

	if ((set) && (ch512 != sisusb->current_font_512)) {

		/* Font is shared among all our consoles.
		 * And so is the hi_font_mask.
		 */
		for (i = 0; i < MAX_NR_CONSOLES; i++) {
			struct vc_data *c = vc_cons[i].d;
			if (c && c->vc_sw == &sisusb_con)
				c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
		}

		sisusb->current_font_512 = ch512;

		/* color plane enable register:
			256-char: enable intensity bit
			512-char: disable intensity bit */
		sisusb_getreg(sisusb, SISINPSTAT, &dummy);
		sisusb_setreg(sisusb, SISAR, 0x12);
		sisusb_setreg(sisusb, SISAR, ch512 ? 0x07 : 0x0f);

		sisusb_getreg(sisusb, SISINPSTAT, &dummy);
		sisusb_setreg(sisusb, SISAR, 0x20);
		sisusb_getreg(sisusb, SISINPSTAT, &dummy);
	}

	if (dorecalc) {

		/*
		 * Adjust the screen to fit a font of a certain height
		 */

		unsigned char ovr, vde, fsr;
		int rows = 0, maxscan = 0;

		if (c) {

			/* Number of video rows */
			rows = c->vc_scan_lines / fh;
			/* Scan lines to actually display-1 */
			maxscan = rows * fh - 1;

			/*printk(KERN_DEBUG "sisusb recalc rows %d maxscan %d fh %d sl %d\n",
				rows, maxscan, fh, c->vc_scan_lines);*/

			sisusb_getidxreg(sisusb, SISCR, 0x07, &ovr);
			vde = maxscan & 0xff;
			ovr = (ovr & 0xbd) |
			      ((maxscan & 0x100) >> 7) |
			      ((maxscan & 0x200) >> 3);
			sisusb_setidxreg(sisusb, SISCR, 0x07, ovr);
			sisusb_setidxreg(sisusb, SISCR, 0x12, vde);

		}

		sisusb_getidxreg(sisusb, SISCR, 0x09, &fsr);
		fsr = (fsr & 0xe0) | (fh - 1);
		sisusb_setidxreg(sisusb, SISCR, 0x09, fsr);
		sisusb->current_font_height = fh;

		sisusb->sisusb_cursor_size_from = -1;
		sisusb->sisusb_cursor_size_to   = -1;

	}

	if (uplock)
		up(&sisusb->lock);

	if (dorecalc && c) {
		int i, rows = c->vc_scan_lines / fh;

		/* Now adjust our consoles' size */

		for (i = 0; i < MAX_NR_CONSOLES; i++) {
			struct vc_data *vc = vc_cons[i].d;

			if (vc && vc->vc_sw == &sisusb_con) {
				if (CON_IS_VISIBLE(vc)) {
					vc->vc_sw->con_cursor(vc, CM_DRAW);
				}
				vc->vc_font.height = fh;
				vc_resize(vc, 0, rows);
			}
		}
	}

	return 0;

font_op_error:
	if (uplock)
		up(&sisusb->lock);

	return -EIO;
}

/* Interface routine */
static int
sisusbcon_font_set(struct vc_data *c, struct console_font *font,
							unsigned flags)
{
	struct sisusb_usb_data *sisusb;
	unsigned charcount = font->charcount;

	if (font->width != 8 || (charcount != 256 && charcount != 512))
		return -EINVAL;

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return -ENODEV;

	/* sisusb->lock is down */

	/* Save the user-provided font into a buffer. This
	 * is used for restoring text mode after quitting
	 * from X and for the con_getfont routine.
	 */
	if (sisusb->font_backup) {
		if (sisusb->font_backup_size < charcount) {
			vfree(sisusb->font_backup);
			sisusb->font_backup = NULL;
		}
	}

	if (!sisusb->font_backup)
		sisusb->font_backup = vmalloc(charcount * 32);

	if (sisusb->font_backup) {
		memcpy(sisusb->font_backup, font->data, charcount * 32);
		sisusb->font_backup_size = charcount;
		sisusb->font_backup_height = font->height;
		sisusb->font_backup_512 = (charcount == 512) ? 1 : 0;
	}

	/* do_font_op ups sisusb->lock */

	return sisusbcon_do_font_op(sisusb, 1, 2, font->data,
			8192, (charcount == 512),
			(!(flags & KD_FONT_FLAG_DONT_RECALC)) ? 1 : 0,
			c, font->height, 1);
}

/* Interface routine */
static int
sisusbcon_font_get(struct vc_data *c, struct console_font *font)
{
	struct sisusb_usb_data *sisusb;

	if (!(sisusb = sisusb_get_sisusb_lock_and_check(c->vc_num)))
		return -ENODEV;

	/* sisusb->lock is down */

	font->width = 8;
	font->height = c->vc_font.height;
	font->charcount = 256;

	if (!font->data) {
		up(&sisusb->lock);
		return 0;
	}

	if (!sisusb->font_backup) {
		up(&sisusb->lock);
		return -ENODEV;
	}

	/* Copy 256 chars only, like vgacon */
	memcpy(font->data, sisusb->font_backup, 256 * 32);

	up(&sisusb->lock);

	return 0;
}

/*
 *  The console `switch' structure for the sisusb console
 */

static const struct consw sisusb_con = {
	.owner =		THIS_MODULE,
	.con_startup =		sisusbcon_startup,
	.con_init =		sisusbcon_init,
	.con_deinit =		sisusbcon_deinit,
	.con_clear =		sisusbcon_clear,
	.con_putc =		sisusbcon_putc,
	.con_putcs =		sisusbcon_putcs,
	.con_cursor =		sisusbcon_cursor,
	.con_scroll =		sisusbcon_scroll,
	.con_bmove =		sisusbcon_bmove,
	.con_switch =		sisusbcon_switch,
	.con_blank =		sisusbcon_blank,
	.con_font_set =		sisusbcon_font_set,
	.con_font_get =		sisusbcon_font_get,
	.con_set_palette =	sisusbcon_set_palette,
	.con_scrolldelta =	sisusbcon_scrolldelta,
	.con_build_attr =	sisusbcon_build_attr,
	.con_invert_region =	sisusbcon_invert_region,
	.con_set_origin =	sisusbcon_set_origin,
	.con_save_screen =	sisusbcon_save_screen,
	.con_resize =		sisusbcon_resize,
};

/* Our very own dummy console driver */

static const char *sisusbdummycon_startup(void)
{
    return "SISUSBVGADUMMY";
}

static void sisusbdummycon_init(struct vc_data *vc, int init)
{
    vc->vc_can_do_color = 1;
    if (init) {
	vc->vc_cols = 80;
	vc->vc_rows = 25;
    } else
	vc_resize(vc, 80, 25);
}

static int sisusbdummycon_dummy(void)
{
    return 0;
}

#define SISUSBCONDUMMY	(void *)sisusbdummycon_dummy

const struct consw sisusb_dummy_con = {
	.owner =		THIS_MODULE,
	.con_startup =		sisusbdummycon_startup,
	.con_init =		sisusbdummycon_init,
	.con_deinit =		SISUSBCONDUMMY,
	.con_clear =		SISUSBCONDUMMY,
	.con_putc =		SISUSBCONDUMMY,
	.con_putcs =		SISUSBCONDUMMY,
	.con_cursor =		SISUSBCONDUMMY,
	.con_scroll =		SISUSBCONDUMMY,
	.con_bmove =		SISUSBCONDUMMY,
	.con_switch =		SISUSBCONDUMMY,
	.con_blank =		SISUSBCONDUMMY,
	.con_font_set =		SISUSBCONDUMMY,
	.con_font_get =		SISUSBCONDUMMY,
	.con_font_default =	SISUSBCONDUMMY,
	.con_font_copy =	SISUSBCONDUMMY,
	.con_set_palette =	SISUSBCONDUMMY,
	.con_scrolldelta =	SISUSBCONDUMMY,
};

int
sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last)
{
	int i, ret, minor = sisusb->minor;

	down(&disconnect_sem);

	down(&sisusb->lock);

	/* Erm.. that should not happen */
	if (sisusb->haveconsole || !sisusb->SiS_Pr) {
		up(&sisusb->lock);
		up(&disconnect_sem);
		return 1;
	}

	sisusb->con_first = first;
	sisusb->con_last  = last;

	if (first > last ||
	    first > MAX_NR_CONSOLES ||
	    last > MAX_NR_CONSOLES) {
		up(&sisusb->lock);
		up(&disconnect_sem);
		return 1;
	}

	/* If gfxcore not initialized or no consoles given, quit graciously */
	if (!sisusb->gfxinit || first < 1 || last < 1) {
		up(&sisusb->lock);
		up(&disconnect_sem);
		return 0;
	}

	sisusb->sisusb_cursor_loc       = -1;
	sisusb->sisusb_cursor_size_from = -1;
	sisusb->sisusb_cursor_size_to   = -1;

	/* Set up text mode (and upload  default font) */
	if (sisusb_reset_text_mode(sisusb, 1)) {
		up(&sisusb->lock);
		up(&disconnect_sem);
		printk(KERN_ERR
			"sisusbvga[%d]: Failed to set up text mode\n",
			minor);
		return 1;
	}

	/* Initialize some gfx registers */
	sisusb_initialize(sisusb);

	for (i = first - 1; i <= last - 1; i++) {
		/* Save sisusb for our interface routines */
		mysisusbs[i] = sisusb;
	}

	/* Initial console setup */
	sisusb->sisusb_num_columns = 80;

	/* Use a 32K buffer (matches b8000-bffff area) */
	sisusb->scrbuf_size = 32 * 1024;

	/* Allocate screen buffer */
	if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) {
		up(&sisusb->lock);
		up(&disconnect_sem);
		printk(KERN_ERR
			"sisusbvga[%d]: Failed to allocate screen buffer\n",
			minor);
		return 1;
	}

	up(&sisusb->lock);
	up(&disconnect_sem);

	/* Now grab the desired console(s) */
	ret = take_over_console(&sisusb_con, first - 1, last - 1, 0);

	if (!ret)
		sisusb->haveconsole = 1;
	else {
		for (i = first - 1; i <= last - 1; i++)
			mysisusbs[i] = NULL;
	}

	return ret;
}

void
sisusb_console_exit(struct sisusb_usb_data *sisusb)
{
	int i;

	/* This is called if the device is disconnected
	 * and while disconnect and lock semaphores
	 * are up. This should be save because we
	 * can't lose our sisusb any other way but by
	 * disconnection (and hence, the disconnect
	 * sema is for protecting all other access
	 * functions from disconnection, not the
	 * other way round).
	 */

	/* Now what do we do in case of disconnection:
	 * One alternative would be to simply call
	 * give_up_console(). Nah, not a good idea.
	 * give_up_console() is obviously buggy as it
	 * only discards the consw pointer from the
	 * driver_map, but doesn't adapt vc->vc_sw
	 * of the affected consoles. Hence, the next
	 * call to any of the console functions will
	 * eventually take a trip to oops county.
	 * Also, give_up_console for some reason
	 * doesn't decrement our module refcount.
	 * Instead, we switch our consoles to a private
	 * dummy console. This, of course, keeps our
	 * refcount up as well, but it works perfectly.
	 */

	if (sisusb->haveconsole) {
		for (i = 0; i < MAX_NR_CONSOLES; i++)
			if (sisusb->havethisconsole[i])
				take_over_console(&sisusb_dummy_con, i, i, 0);
				/* At this point, con_deinit for all our
				 * consoles is executed by take_over_console().
				 */
		sisusb->haveconsole = 0;
	}

	vfree((void *)sisusb->scrbuf);
	sisusb->scrbuf = 0;

	vfree(sisusb->font_backup);
	sisusb->font_backup = NULL;
}

void __init sisusb_init_concode(void)
{
	int i;

	for (i = 0; i < MAX_NR_CONSOLES; i++)
		mysisusbs[i] = NULL;
}

#endif /* INCL_CON */



