/*
 *    ebcdic keycode functions for s390 console drivers
 *
 *  S390 version
 *    Copyright IBM Corp. 2003
 *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
 */

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/sysrq.h>

#include <linux/consolemap.h>
#include <linux/kbd_kern.h>
#include <linux/kbd_diacr.h>
#include <asm/uaccess.h>

#include "keyboard.h"

/*
 * Handler Tables.
 */
#define K_HANDLERS\
	k_self,		k_fn,		k_spec,		k_ignore,\
	k_dead,		k_ignore,	k_ignore,	k_ignore,\
	k_ignore,	k_ignore,	k_ignore,	k_ignore,\
	k_ignore,	k_ignore,	k_ignore,	k_ignore

typedef void (k_handler_fn)(struct kbd_data *, unsigned char);
static k_handler_fn K_HANDLERS;
static k_handler_fn *k_handler[16] = { K_HANDLERS };

/* maximum values each key_handler can handle */
static const int kbd_max_vals[] = {
	255, ARRAY_SIZE(func_table) - 1, NR_FN_HANDLER - 1, 0,
	NR_DEAD - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static const int KBD_NR_TYPES = ARRAY_SIZE(kbd_max_vals);

static unsigned char ret_diacr[NR_DEAD] = {
	'`', '\'', '^', '~', '"', ','
};

/*
 * Alloc/free of kbd_data structures.
 */
struct kbd_data *
kbd_alloc(void) {
	struct kbd_data *kbd;
	int i;

	kbd = kzalloc(sizeof(struct kbd_data), GFP_KERNEL);
	if (!kbd)
		goto out;
	kbd->key_maps = kzalloc(sizeof(key_maps), GFP_KERNEL);
	if (!kbd->key_maps)
		goto out_kbd;
	for (i = 0; i < ARRAY_SIZE(key_maps); i++) {
		if (key_maps[i]) {
			kbd->key_maps[i] = kmemdup(key_maps[i],
						   sizeof(u_short) * NR_KEYS,
						   GFP_KERNEL);
			if (!kbd->key_maps[i])
				goto out_maps;
		}
	}
	kbd->func_table = kzalloc(sizeof(func_table), GFP_KERNEL);
	if (!kbd->func_table)
		goto out_maps;
	for (i = 0; i < ARRAY_SIZE(func_table); i++) {
		if (func_table[i]) {
			kbd->func_table[i] = kstrdup(func_table[i],
						     GFP_KERNEL);
			if (!kbd->func_table[i])
				goto out_func;
		}
	}
	kbd->fn_handler =
		kzalloc(sizeof(fn_handler_fn *) * NR_FN_HANDLER, GFP_KERNEL);
	if (!kbd->fn_handler)
		goto out_func;
	kbd->accent_table = kmemdup(accent_table,
				    sizeof(struct kbdiacruc) * MAX_DIACR,
				    GFP_KERNEL);
	if (!kbd->accent_table)
		goto out_fn_handler;
	kbd->accent_table_size = accent_table_size;
	return kbd;

out_fn_handler:
	kfree(kbd->fn_handler);
out_func:
	for (i = 0; i < ARRAY_SIZE(func_table); i++)
		kfree(kbd->func_table[i]);
	kfree(kbd->func_table);
out_maps:
	for (i = 0; i < ARRAY_SIZE(key_maps); i++)
		kfree(kbd->key_maps[i]);
	kfree(kbd->key_maps);
out_kbd:
	kfree(kbd);
out:
	return NULL;
}

void
kbd_free(struct kbd_data *kbd)
{
	int i;

	kfree(kbd->accent_table);
	kfree(kbd->fn_handler);
	for (i = 0; i < ARRAY_SIZE(func_table); i++)
		kfree(kbd->func_table[i]);
	kfree(kbd->func_table);
	for (i = 0; i < ARRAY_SIZE(key_maps); i++)
		kfree(kbd->key_maps[i]);
	kfree(kbd->key_maps);
	kfree(kbd);
}

/*
 * Generate ascii -> ebcdic translation table from kbd_data.
 */
void
kbd_ascebc(struct kbd_data *kbd, unsigned char *ascebc)
{
	unsigned short *keymap, keysym;
	int i, j, k;

	memset(ascebc, 0x40, 256);
	for (i = 0; i < ARRAY_SIZE(key_maps); i++) {
		keymap = kbd->key_maps[i];
		if (!keymap)
			continue;
		for (j = 0; j < NR_KEYS; j++) {
			k = ((i & 1) << 7) + j;
			keysym = keymap[j];
			if (KTYP(keysym) == (KT_LATIN | 0xf0) ||
			    KTYP(keysym) == (KT_LETTER | 0xf0))
				ascebc[KVAL(keysym)] = k;
			else if (KTYP(keysym) == (KT_DEAD | 0xf0))
				ascebc[ret_diacr[KVAL(keysym)]] = k;
		}
	}
}

#if 0
/*
 * Generate ebcdic -> ascii translation table from kbd_data.
 */
void
kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc)
{
	unsigned short *keymap, keysym;
	int i, j, k;

	memset(ebcasc, ' ', 256);
	for (i = 0; i < ARRAY_SIZE(key_maps); i++) {
		keymap = kbd->key_maps[i];
		if (!keymap)
			continue;
		for (j = 0; j < NR_KEYS; j++) {
			keysym = keymap[j];
			k = ((i & 1) << 7) + j;
			if (KTYP(keysym) == (KT_LATIN | 0xf0) ||
			    KTYP(keysym) == (KT_LETTER | 0xf0))
				ebcasc[k] = KVAL(keysym);
			else if (KTYP(keysym) == (KT_DEAD | 0xf0))
				ebcasc[k] = ret_diacr[KVAL(keysym)];
		}
	}
}
#endif

/*
 * We have a combining character DIACR here, followed by the character CH.
 * If the combination occurs in the table, return the corresponding value.
 * Otherwise, if CH is a space or equals DIACR, return DIACR.
 * Otherwise, conclude that DIACR was not combining after all,
 * queue it and return CH.
 */
static unsigned int
handle_diacr(struct kbd_data *kbd, unsigned int ch)
{
	int i, d;

	d = kbd->diacr;
	kbd->diacr = 0;

	for (i = 0; i < kbd->accent_table_size; i++) {
		if (kbd->accent_table[i].diacr == d &&
		    kbd->accent_table[i].base == ch)
			return kbd->accent_table[i].result;
	}

	if (ch == ' ' || ch == d)
		return d;

	kbd_put_queue(kbd->port, d);
	return ch;
}

/*
 * Handle dead key.
 */
static void
k_dead(struct kbd_data *kbd, unsigned char value)
{
	value = ret_diacr[value];
	kbd->diacr = (kbd->diacr ? handle_diacr(kbd, value) : value);
}

/*
 * Normal character handler.
 */
static void
k_self(struct kbd_data *kbd, unsigned char value)
{
	if (kbd->diacr)
		value = handle_diacr(kbd, value);
	kbd_put_queue(kbd->port, value);
}

/*
 * Special key handlers
 */
static void
k_ignore(struct kbd_data *kbd, unsigned char value)
{
}

/*
 * Function key handler.
 */
static void
k_fn(struct kbd_data *kbd, unsigned char value)
{
	if (kbd->func_table[value])
		kbd_puts_queue(kbd->port, kbd->func_table[value]);
}

static void
k_spec(struct kbd_data *kbd, unsigned char value)
{
	if (value >= NR_FN_HANDLER)
		return;
	if (kbd->fn_handler[value])
		kbd->fn_handler[value](kbd);
}

/*
 * Put utf8 character to tty flip buffer.
 * UTF-8 is defined for words of up to 31 bits,
 * but we need only 16 bits here
 */
static void
to_utf8(struct tty_port *port, ushort c)
{
	if (c < 0x80)
		/*  0******* */
		kbd_put_queue(port, c);
	else if (c < 0x800) {
		/* 110***** 10****** */
		kbd_put_queue(port, 0xc0 | (c >> 6));
		kbd_put_queue(port, 0x80 | (c & 0x3f));
	} else {
		/* 1110**** 10****** 10****** */
		kbd_put_queue(port, 0xe0 | (c >> 12));
		kbd_put_queue(port, 0x80 | ((c >> 6) & 0x3f));
		kbd_put_queue(port, 0x80 | (c & 0x3f));
	}
}

/*
 * Process keycode.
 */
void
kbd_keycode(struct kbd_data *kbd, unsigned int keycode)
{
	unsigned short keysym;
	unsigned char type, value;

	if (!kbd)
		return;

	if (keycode >= 384)
		keysym = kbd->key_maps[5][keycode - 384];
	else if (keycode >= 256)
		keysym = kbd->key_maps[4][keycode - 256];
	else if (keycode >= 128)
		keysym = kbd->key_maps[1][keycode - 128];
	else
		keysym = kbd->key_maps[0][keycode];

	type = KTYP(keysym);
	if (type >= 0xf0) {
		type -= 0xf0;
		if (type == KT_LETTER)
			type = KT_LATIN;
		value = KVAL(keysym);
#ifdef CONFIG_MAGIC_SYSRQ	       /* Handle the SysRq Hack */
		if (kbd->sysrq) {
			if (kbd->sysrq == K(KT_LATIN, '-')) {
				kbd->sysrq = 0;
				handle_sysrq(value);
				return;
			}
			if (value == '-') {
				kbd->sysrq = K(KT_LATIN, '-');
				return;
			}
			/* Incomplete sysrq sequence. */
			(*k_handler[KTYP(kbd->sysrq)])(kbd, KVAL(kbd->sysrq));
			kbd->sysrq = 0;
		} else if ((type == KT_LATIN && value == '^') ||
			   (type == KT_DEAD && ret_diacr[value] == '^')) {
			kbd->sysrq = K(type, value);
			return;
		}
#endif
		(*k_handler[type])(kbd, value);
	} else
		to_utf8(kbd->port, keysym);
}

/*
 * Ioctl stuff.
 */
static int
do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry __user *user_kbe,
	      int cmd, int perm)
{
	struct kbentry tmp;
	ushort *key_map, val, ov;

	if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
		return -EFAULT;
#if NR_KEYS < 256
	if (tmp.kb_index >= NR_KEYS)
		return -EINVAL;
#endif
#if MAX_NR_KEYMAPS < 256
	if (tmp.kb_table >= MAX_NR_KEYMAPS)
		return -EINVAL;	
#endif

	switch (cmd) {
	case KDGKBENT:
		key_map = kbd->key_maps[tmp.kb_table];
		if (key_map) {
		    val = U(key_map[tmp.kb_index]);
		    if (KTYP(val) >= KBD_NR_TYPES)
			val = K_HOLE;
		} else
		    val = (tmp.kb_index ? K_HOLE : K_NOSUCHMAP);
		return put_user(val, &user_kbe->kb_value);
	case KDSKBENT:
		if (!perm)
			return -EPERM;
		if (!tmp.kb_index && tmp.kb_value == K_NOSUCHMAP) {
			/* disallocate map */
			key_map = kbd->key_maps[tmp.kb_table];
			if (key_map) {
			    kbd->key_maps[tmp.kb_table] = NULL;
			    kfree(key_map);
			}
			break;
		}

		if (KTYP(tmp.kb_value) >= KBD_NR_TYPES)
			return -EINVAL;
		if (KVAL(tmp.kb_value) > kbd_max_vals[KTYP(tmp.kb_value)])
			return -EINVAL;

		if (!(key_map = kbd->key_maps[tmp.kb_table])) {
			int j;

			key_map = kmalloc(sizeof(plain_map),
						     GFP_KERNEL);
			if (!key_map)
				return -ENOMEM;
			kbd->key_maps[tmp.kb_table] = key_map;
			for (j = 0; j < NR_KEYS; j++)
				key_map[j] = U(K_HOLE);
		}
		ov = U(key_map[tmp.kb_index]);
		if (tmp.kb_value == ov)
			break;	/* nothing to do */
		/*
		 * Attention Key.
		 */
		if (((ov == K_SAK) || (tmp.kb_value == K_SAK)) &&
		    !capable(CAP_SYS_ADMIN))
			return -EPERM;
		key_map[tmp.kb_index] = U(tmp.kb_value);
		break;
	}
	return 0;
}

static int
do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs,
	       int cmd, int perm)
{
	unsigned char kb_func;
	char *p;
	int len;

	/* Get u_kbs->kb_func. */
	if (get_user(kb_func, &u_kbs->kb_func))
		return -EFAULT;
#if MAX_NR_FUNC < 256
	if (kb_func >= MAX_NR_FUNC)
		return -EINVAL;
#endif

	switch (cmd) {
	case KDGKBSENT:
		p = kbd->func_table[kb_func];
		if (p) {
			len = strlen(p);
			if (len >= sizeof(u_kbs->kb_string))
				len = sizeof(u_kbs->kb_string) - 1;
			if (copy_to_user(u_kbs->kb_string, p, len))
				return -EFAULT;
		} else
			len = 0;
		if (put_user('\0', u_kbs->kb_string + len))
			return -EFAULT;
		break;
	case KDSKBSENT:
		if (!perm)
			return -EPERM;
		len = strnlen_user(u_kbs->kb_string,
				   sizeof(u_kbs->kb_string) - 1);
		if (!len)
			return -EFAULT;
		if (len > sizeof(u_kbs->kb_string) - 1)
			return -EINVAL;
		p = kmalloc(len + 1, GFP_KERNEL);
		if (!p)
			return -ENOMEM;
		if (copy_from_user(p, u_kbs->kb_string, len)) {
			kfree(p);
			return -EFAULT;
		}
		p[len] = 0;
		kfree(kbd->func_table[kb_func]);
		kbd->func_table[kb_func] = p;
		break;
	}
	return 0;
}

int kbd_ioctl(struct kbd_data *kbd, unsigned int cmd, unsigned long arg)
{
	struct tty_struct *tty;
	void __user *argp;
	unsigned int ct;
	int perm;

	argp = (void __user *)arg;

	/*
	 * To have permissions to do most of the vt ioctls, we either have
	 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
	 */
	tty = tty_port_tty_get(kbd->port);
	/* FIXME this test is pretty racy */
	perm = current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG);
	tty_kref_put(tty);
	switch (cmd) {
	case KDGKBTYPE:
		return put_user(KB_101, (char __user *)argp);
	case KDGKBENT:
	case KDSKBENT:
		return do_kdsk_ioctl(kbd, argp, cmd, perm);
	case KDGKBSENT:
	case KDSKBSENT:
		return do_kdgkb_ioctl(kbd, argp, cmd, perm);
	case KDGKBDIACR:
	{
		struct kbdiacrs __user *a = argp;
		struct kbdiacr diacr;
		int i;

		if (put_user(kbd->accent_table_size, &a->kb_cnt))
			return -EFAULT;
		for (i = 0; i < kbd->accent_table_size; i++) {
			diacr.diacr = kbd->accent_table[i].diacr;
			diacr.base = kbd->accent_table[i].base;
			diacr.result = kbd->accent_table[i].result;
			if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr)))
			return -EFAULT;
		}
		return 0;
	}
	case KDGKBDIACRUC:
	{
		struct kbdiacrsuc __user *a = argp;

		ct = kbd->accent_table_size;
		if (put_user(ct, &a->kb_cnt))
			return -EFAULT;
		if (copy_to_user(a->kbdiacruc, kbd->accent_table,
				 ct * sizeof(struct kbdiacruc)))
			return -EFAULT;
		return 0;
	}
	case KDSKBDIACR:
	{
		struct kbdiacrs __user *a = argp;
		struct kbdiacr diacr;
		int i;

		if (!perm)
			return -EPERM;
		if (get_user(ct, &a->kb_cnt))
			return -EFAULT;
		if (ct >= MAX_DIACR)
			return -EINVAL;
		kbd->accent_table_size = ct;
		for (i = 0; i < ct; i++) {
			if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr)))
				return -EFAULT;
			kbd->accent_table[i].diacr = diacr.diacr;
			kbd->accent_table[i].base = diacr.base;
			kbd->accent_table[i].result = diacr.result;
		}
		return 0;
	}
	case KDSKBDIACRUC:
	{
		struct kbdiacrsuc __user *a = argp;

		if (!perm)
			return -EPERM;
		if (get_user(ct, &a->kb_cnt))
			return -EFAULT;
		if (ct >= MAX_DIACR)
			return -EINVAL;
		kbd->accent_table_size = ct;
		if (copy_from_user(kbd->accent_table, a->kbdiacruc,
				   ct * sizeof(struct kbdiacruc)))
			return -EFAULT;
		return 0;
	}
	default:
		return -ENOIOCTLCMD;
	}
}

EXPORT_SYMBOL(kbd_ioctl);
EXPORT_SYMBOL(kbd_ascebc);
EXPORT_SYMBOL(kbd_free);
EXPORT_SYMBOL(kbd_alloc);
EXPORT_SYMBOL(kbd_keycode);
