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

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

#include <linux/consolemap.h>
#include <linux/kbd_kern.h>
#include <linux/kbd_diacr.h>
#include <linux/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 const unsigned char ret_diacr[NR_DEAD] = {
	'`',	/* dead_grave */
	'\'',	/* dead_acute */
	'^',	/* dead_circumflex */
	'~',	/* dead_tilda */
	'"',	/* dead_diaeresis */
	',',	/* dead_cedilla */
	'_',	/* dead_macron */
	'U',	/* dead_breve */
	'.',	/* dead_abovedot */
	'*',	/* dead_abovering */
	'=',	/* dead_doubleacute */
	'c',	/* dead_caron */
	'k',	/* dead_ogonek */
	'i',	/* dead_iota */
	'#',	/* dead_voiced_sound */
	'o',	/* dead_semivoiced_sound */
	'!',	/* dead_belowdot */
	'?',	/* dead_hook */
	'+',	/* dead_horn */
	'-',	/* dead_stroke */
	')',	/* dead_abovecomma */
	'(',	/* dead_abovereversedcomma */
	':',	/* dead_doublegrave */
	'n',	/* dead_invertedbreve */
	';',	/* dead_belowcomma */
	'$',	/* dead_currency */
	'@',	/* dead_greek */
};

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

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

out_fn_handler:
	kfree(kbd->fn_handler);
out_func:
	for (i = 0; i < ARRAY_SIZE(ebc_func_table); i++)
		kfree(kbd->func_table[i]);
	kfree(kbd->func_table);
out_maps:
	for (i = 0; i < ARRAY_SIZE(ebc_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(ebc_func_table); i++)
		kfree(kbd->func_table[i]);
	kfree(kbd->func_table);
	for (i = 0; i < ARRAY_SIZE(ebc_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(ebc_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(ebc_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;
	unsigned long kb_index, kb_table;
	ushort *key_map, val, ov;

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

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

			key_map = kmalloc(sizeof(plain_map),
						     GFP_KERNEL);
			if (!key_map)
				return -ENOMEM;
			kbd->key_maps[kb_table] = key_map;
			for (j = 0; j < NR_KEYS; j++)
				key_map[j] = U(K_HOLE);
		}
		ov = U(key_map[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[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;
		p = strndup_user(u_kbs->kb_string, sizeof(u_kbs->kb_string));
		if (IS_ERR(p))
			return PTR_ERR(p);
		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);
