/*
 *  drivers/s390/char/keyboard.c
 *    ebcdic keycode functions for s390 console drivers
 *
 *  S390 version
 *    Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/sysrq.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, len;

	kbd = kmalloc(sizeof(struct kbd_data), GFP_KERNEL);
	if (!kbd)
		goto out;
	memset(kbd, 0, sizeof(struct kbd_data));
	kbd->key_maps = kmalloc(sizeof(key_maps), GFP_KERNEL);
	if (!key_maps)
		goto out_kbd;
	memset(kbd->key_maps, 0, sizeof(key_maps));
	for (i = 0; i < ARRAY_SIZE(key_maps); i++) {
		if (key_maps[i]) {
			kbd->key_maps[i] =
				kmalloc(sizeof(u_short)*NR_KEYS, GFP_KERNEL);
			if (!kbd->key_maps[i])
				goto out_maps;
			memcpy(kbd->key_maps[i], key_maps[i],
			       sizeof(u_short)*NR_KEYS);
		}
	}
	kbd->func_table = kmalloc(sizeof(func_table), GFP_KERNEL);
	if (!kbd->func_table)
		goto out_maps;
	memset(kbd->func_table, 0, sizeof(func_table));
	for (i = 0; i < ARRAY_SIZE(func_table); i++) {
		if (func_table[i]) {
			len = strlen(func_table[i]) + 1;
			kbd->func_table[i] = kmalloc(len, GFP_KERNEL);
			if (!kbd->func_table[i])
				goto out_func;
			memcpy(kbd->func_table[i], func_table[i], len);
		}
	}
	kbd->fn_handler =
		kmalloc(sizeof(fn_handler_fn *) * NR_FN_HANDLER, GFP_KERNEL);
	if (!kbd->fn_handler)
		goto out_func;
	memset(kbd->fn_handler, 0, sizeof(fn_handler_fn *) * NR_FN_HANDLER);
	kbd->accent_table =
		kmalloc(sizeof(struct kbdiacr)*MAX_DIACR, GFP_KERNEL);
	if (!kbd->accent_table)
		goto out_fn_handler;
	memcpy(kbd->accent_table, accent_table,
	       sizeof(struct kbdiacr)*MAX_DIACR);
	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++)
		if (kbd->func_table[i])
			kfree(kbd->func_table[i]);
	kfree(kbd->func_table);
out_maps:
	for (i = 0; i < ARRAY_SIZE(key_maps); i++)
		if (kbd->key_maps[i])
			kfree(kbd->key_maps[i]);
	kfree(kbd->key_maps);
out_kbd:
	kfree(kbd);
out:
	return 0;
}

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++)
		if (kbd->func_table[i])
			kfree(kbd->func_table[i]);
	kfree(kbd->func_table);
	for (i = 0; i < ARRAY_SIZE(key_maps); i++)
		if (kbd->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;
		}
	}
}

/*
 * 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)];
		}
	}
}

/*
 * 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 char
handle_diacr(struct kbd_data *kbd, unsigned char 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->tty, 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->tty, 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->tty, 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_struct *tty, ushort c) 
{
	if (c < 0x80)
		/*  0******* */
		kbd_put_queue(tty, c);
	else if (c < 0x800) {
		/* 110***** 10****** */
		kbd_put_queue(tty, 0xc0 | (c >> 6));
		kbd_put_queue(tty, 0x80 | (c & 0x3f));
	} else {
		/* 1110**** 10****** 10****** */
		kbd_put_queue(tty, 0xe0 | (c >> 12));
		kbd_put_queue(tty, 0x80 | ((c >> 6) & 0x3f));
		kbd_put_queue(tty, 0x80 | (c & 0x3f));
	}
}

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

	if (!kbd || !kbd->tty)
		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, 0, kbd->tty);
				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->tty, 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] = 0;
			    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 = (ushort *) 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);
		p = kmalloc(len, GFP_KERNEL);
		if (!p)
			return -ENOMEM;
		if (copy_from_user(p, u_kbs->kb_string, len)) {
			kfree(p);
			return -EFAULT;
		}
		p[len] = 0;
		if (kbd->func_table[kb_func])
			kfree(kbd->func_table[kb_func]);
		kbd->func_table[kb_func] = p;
		break;
	}
	return 0;
}

int
kbd_ioctl(struct kbd_data *kbd, struct file *file,
	  unsigned int cmd, unsigned long arg)
{
	struct kbdiacrs __user *a;
	void __user *argp;
	int ct, 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.
	 */
	perm = current->signal->tty == kbd->tty || capable(CAP_SYS_TTY_CONFIG);
	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:
		a = argp;

		if (put_user(kbd->accent_table_size, &a->kb_cnt))
			return -EFAULT;
		ct = kbd->accent_table_size;
		if (copy_to_user(a->kbdiacr, kbd->accent_table,
				 ct * sizeof(struct kbdiacr)))
			return -EFAULT;
		return 0;
	case KDSKBDIACR:
		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->kbdiacr,
				   ct * sizeof(struct kbdiacr)))
			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);
