1 /* 2 * drivers/s390/char/keyboard.c 3 * ebcdic keycode functions for s390 console drivers 4 * 5 * S390 version 6 * Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), 8 */ 9 10 #include <linux/module.h> 11 #include <linux/sched.h> 12 #include <linux/sysrq.h> 13 14 #include <linux/consolemap.h> 15 #include <linux/kbd_kern.h> 16 #include <linux/kbd_diacr.h> 17 #include <asm/uaccess.h> 18 19 #include "keyboard.h" 20 21 /* 22 * Handler Tables. 23 */ 24 #define K_HANDLERS\ 25 k_self, k_fn, k_spec, k_ignore,\ 26 k_dead, k_ignore, k_ignore, k_ignore,\ 27 k_ignore, k_ignore, k_ignore, k_ignore,\ 28 k_ignore, k_ignore, k_ignore, k_ignore 29 30 typedef void (k_handler_fn)(struct kbd_data *, unsigned char); 31 static k_handler_fn K_HANDLERS; 32 static k_handler_fn *k_handler[16] = { K_HANDLERS }; 33 34 /* maximum values each key_handler can handle */ 35 static const int kbd_max_vals[] = { 36 255, ARRAY_SIZE(func_table) - 1, NR_FN_HANDLER - 1, 0, 37 NR_DEAD - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 38 }; 39 static const int KBD_NR_TYPES = ARRAY_SIZE(kbd_max_vals); 40 41 static unsigned char ret_diacr[NR_DEAD] = { 42 '`', '\'', '^', '~', '"', ',' 43 }; 44 45 /* 46 * Alloc/free of kbd_data structures. 47 */ 48 struct kbd_data * 49 kbd_alloc(void) { 50 struct kbd_data *kbd; 51 int i, len; 52 53 kbd = kzalloc(sizeof(struct kbd_data), GFP_KERNEL); 54 if (!kbd) 55 goto out; 56 kbd->key_maps = kzalloc(sizeof(key_maps), GFP_KERNEL); 57 if (!kbd->key_maps) 58 goto out_kbd; 59 for (i = 0; i < ARRAY_SIZE(key_maps); i++) { 60 if (key_maps[i]) { 61 kbd->key_maps[i] = 62 kmalloc(sizeof(u_short)*NR_KEYS, GFP_KERNEL); 63 if (!kbd->key_maps[i]) 64 goto out_maps; 65 memcpy(kbd->key_maps[i], key_maps[i], 66 sizeof(u_short)*NR_KEYS); 67 } 68 } 69 kbd->func_table = kzalloc(sizeof(func_table), GFP_KERNEL); 70 if (!kbd->func_table) 71 goto out_maps; 72 for (i = 0; i < ARRAY_SIZE(func_table); i++) { 73 if (func_table[i]) { 74 len = strlen(func_table[i]) + 1; 75 kbd->func_table[i] = kmalloc(len, GFP_KERNEL); 76 if (!kbd->func_table[i]) 77 goto out_func; 78 memcpy(kbd->func_table[i], func_table[i], len); 79 } 80 } 81 kbd->fn_handler = 82 kzalloc(sizeof(fn_handler_fn *) * NR_FN_HANDLER, GFP_KERNEL); 83 if (!kbd->fn_handler) 84 goto out_func; 85 kbd->accent_table = 86 kmalloc(sizeof(struct kbdiacruc)*MAX_DIACR, GFP_KERNEL); 87 if (!kbd->accent_table) 88 goto out_fn_handler; 89 memcpy(kbd->accent_table, accent_table, 90 sizeof(struct kbdiacruc)*MAX_DIACR); 91 kbd->accent_table_size = accent_table_size; 92 return kbd; 93 94 out_fn_handler: 95 kfree(kbd->fn_handler); 96 out_func: 97 for (i = 0; i < ARRAY_SIZE(func_table); i++) 98 kfree(kbd->func_table[i]); 99 kfree(kbd->func_table); 100 out_maps: 101 for (i = 0; i < ARRAY_SIZE(key_maps); i++) 102 kfree(kbd->key_maps[i]); 103 kfree(kbd->key_maps); 104 out_kbd: 105 kfree(kbd); 106 out: 107 return NULL; 108 } 109 110 void 111 kbd_free(struct kbd_data *kbd) 112 { 113 int i; 114 115 kfree(kbd->accent_table); 116 kfree(kbd->fn_handler); 117 for (i = 0; i < ARRAY_SIZE(func_table); i++) 118 kfree(kbd->func_table[i]); 119 kfree(kbd->func_table); 120 for (i = 0; i < ARRAY_SIZE(key_maps); i++) 121 kfree(kbd->key_maps[i]); 122 kfree(kbd->key_maps); 123 kfree(kbd); 124 } 125 126 /* 127 * Generate ascii -> ebcdic translation table from kbd_data. 128 */ 129 void 130 kbd_ascebc(struct kbd_data *kbd, unsigned char *ascebc) 131 { 132 unsigned short *keymap, keysym; 133 int i, j, k; 134 135 memset(ascebc, 0x40, 256); 136 for (i = 0; i < ARRAY_SIZE(key_maps); i++) { 137 keymap = kbd->key_maps[i]; 138 if (!keymap) 139 continue; 140 for (j = 0; j < NR_KEYS; j++) { 141 k = ((i & 1) << 7) + j; 142 keysym = keymap[j]; 143 if (KTYP(keysym) == (KT_LATIN | 0xf0) || 144 KTYP(keysym) == (KT_LETTER | 0xf0)) 145 ascebc[KVAL(keysym)] = k; 146 else if (KTYP(keysym) == (KT_DEAD | 0xf0)) 147 ascebc[ret_diacr[KVAL(keysym)]] = k; 148 } 149 } 150 } 151 152 #if 0 153 /* 154 * Generate ebcdic -> ascii translation table from kbd_data. 155 */ 156 void 157 kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc) 158 { 159 unsigned short *keymap, keysym; 160 int i, j, k; 161 162 memset(ebcasc, ' ', 256); 163 for (i = 0; i < ARRAY_SIZE(key_maps); i++) { 164 keymap = kbd->key_maps[i]; 165 if (!keymap) 166 continue; 167 for (j = 0; j < NR_KEYS; j++) { 168 keysym = keymap[j]; 169 k = ((i & 1) << 7) + j; 170 if (KTYP(keysym) == (KT_LATIN | 0xf0) || 171 KTYP(keysym) == (KT_LETTER | 0xf0)) 172 ebcasc[k] = KVAL(keysym); 173 else if (KTYP(keysym) == (KT_DEAD | 0xf0)) 174 ebcasc[k] = ret_diacr[KVAL(keysym)]; 175 } 176 } 177 } 178 #endif 179 180 /* 181 * We have a combining character DIACR here, followed by the character CH. 182 * If the combination occurs in the table, return the corresponding value. 183 * Otherwise, if CH is a space or equals DIACR, return DIACR. 184 * Otherwise, conclude that DIACR was not combining after all, 185 * queue it and return CH. 186 */ 187 static unsigned int 188 handle_diacr(struct kbd_data *kbd, unsigned int ch) 189 { 190 int i, d; 191 192 d = kbd->diacr; 193 kbd->diacr = 0; 194 195 for (i = 0; i < kbd->accent_table_size; i++) { 196 if (kbd->accent_table[i].diacr == d && 197 kbd->accent_table[i].base == ch) 198 return kbd->accent_table[i].result; 199 } 200 201 if (ch == ' ' || ch == d) 202 return d; 203 204 kbd_put_queue(kbd->tty, d); 205 return ch; 206 } 207 208 /* 209 * Handle dead key. 210 */ 211 static void 212 k_dead(struct kbd_data *kbd, unsigned char value) 213 { 214 value = ret_diacr[value]; 215 kbd->diacr = (kbd->diacr ? handle_diacr(kbd, value) : value); 216 } 217 218 /* 219 * Normal character handler. 220 */ 221 static void 222 k_self(struct kbd_data *kbd, unsigned char value) 223 { 224 if (kbd->diacr) 225 value = handle_diacr(kbd, value); 226 kbd_put_queue(kbd->tty, value); 227 } 228 229 /* 230 * Special key handlers 231 */ 232 static void 233 k_ignore(struct kbd_data *kbd, unsigned char value) 234 { 235 } 236 237 /* 238 * Function key handler. 239 */ 240 static void 241 k_fn(struct kbd_data *kbd, unsigned char value) 242 { 243 if (kbd->func_table[value]) 244 kbd_puts_queue(kbd->tty, kbd->func_table[value]); 245 } 246 247 static void 248 k_spec(struct kbd_data *kbd, unsigned char value) 249 { 250 if (value >= NR_FN_HANDLER) 251 return; 252 if (kbd->fn_handler[value]) 253 kbd->fn_handler[value](kbd); 254 } 255 256 /* 257 * Put utf8 character to tty flip buffer. 258 * UTF-8 is defined for words of up to 31 bits, 259 * but we need only 16 bits here 260 */ 261 static void 262 to_utf8(struct tty_struct *tty, ushort c) 263 { 264 if (c < 0x80) 265 /* 0******* */ 266 kbd_put_queue(tty, c); 267 else if (c < 0x800) { 268 /* 110***** 10****** */ 269 kbd_put_queue(tty, 0xc0 | (c >> 6)); 270 kbd_put_queue(tty, 0x80 | (c & 0x3f)); 271 } else { 272 /* 1110**** 10****** 10****** */ 273 kbd_put_queue(tty, 0xe0 | (c >> 12)); 274 kbd_put_queue(tty, 0x80 | ((c >> 6) & 0x3f)); 275 kbd_put_queue(tty, 0x80 | (c & 0x3f)); 276 } 277 } 278 279 /* 280 * Process keycode. 281 */ 282 void 283 kbd_keycode(struct kbd_data *kbd, unsigned int keycode) 284 { 285 unsigned short keysym; 286 unsigned char type, value; 287 288 if (!kbd || !kbd->tty) 289 return; 290 291 if (keycode >= 384) 292 keysym = kbd->key_maps[5][keycode - 384]; 293 else if (keycode >= 256) 294 keysym = kbd->key_maps[4][keycode - 256]; 295 else if (keycode >= 128) 296 keysym = kbd->key_maps[1][keycode - 128]; 297 else 298 keysym = kbd->key_maps[0][keycode]; 299 300 type = KTYP(keysym); 301 if (type >= 0xf0) { 302 type -= 0xf0; 303 if (type == KT_LETTER) 304 type = KT_LATIN; 305 value = KVAL(keysym); 306 #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ 307 if (kbd->sysrq) { 308 if (kbd->sysrq == K(KT_LATIN, '-')) { 309 kbd->sysrq = 0; 310 handle_sysrq(value, kbd->tty); 311 return; 312 } 313 if (value == '-') { 314 kbd->sysrq = K(KT_LATIN, '-'); 315 return; 316 } 317 /* Incomplete sysrq sequence. */ 318 (*k_handler[KTYP(kbd->sysrq)])(kbd, KVAL(kbd->sysrq)); 319 kbd->sysrq = 0; 320 } else if ((type == KT_LATIN && value == '^') || 321 (type == KT_DEAD && ret_diacr[value] == '^')) { 322 kbd->sysrq = K(type, value); 323 return; 324 } 325 #endif 326 (*k_handler[type])(kbd, value); 327 } else 328 to_utf8(kbd->tty, keysym); 329 } 330 331 /* 332 * Ioctl stuff. 333 */ 334 static int 335 do_kdsk_ioctl(struct kbd_data *kbd, struct kbentry __user *user_kbe, 336 int cmd, int perm) 337 { 338 struct kbentry tmp; 339 ushort *key_map, val, ov; 340 341 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry))) 342 return -EFAULT; 343 #if NR_KEYS < 256 344 if (tmp.kb_index >= NR_KEYS) 345 return -EINVAL; 346 #endif 347 #if MAX_NR_KEYMAPS < 256 348 if (tmp.kb_table >= MAX_NR_KEYMAPS) 349 return -EINVAL; 350 #endif 351 352 switch (cmd) { 353 case KDGKBENT: 354 key_map = kbd->key_maps[tmp.kb_table]; 355 if (key_map) { 356 val = U(key_map[tmp.kb_index]); 357 if (KTYP(val) >= KBD_NR_TYPES) 358 val = K_HOLE; 359 } else 360 val = (tmp.kb_index ? K_HOLE : K_NOSUCHMAP); 361 return put_user(val, &user_kbe->kb_value); 362 case KDSKBENT: 363 if (!perm) 364 return -EPERM; 365 if (!tmp.kb_index && tmp.kb_value == K_NOSUCHMAP) { 366 /* disallocate map */ 367 key_map = kbd->key_maps[tmp.kb_table]; 368 if (key_map) { 369 kbd->key_maps[tmp.kb_table] = NULL; 370 kfree(key_map); 371 } 372 break; 373 } 374 375 if (KTYP(tmp.kb_value) >= KBD_NR_TYPES) 376 return -EINVAL; 377 if (KVAL(tmp.kb_value) > kbd_max_vals[KTYP(tmp.kb_value)]) 378 return -EINVAL; 379 380 if (!(key_map = kbd->key_maps[tmp.kb_table])) { 381 int j; 382 383 key_map = kmalloc(sizeof(plain_map), 384 GFP_KERNEL); 385 if (!key_map) 386 return -ENOMEM; 387 kbd->key_maps[tmp.kb_table] = key_map; 388 for (j = 0; j < NR_KEYS; j++) 389 key_map[j] = U(K_HOLE); 390 } 391 ov = U(key_map[tmp.kb_index]); 392 if (tmp.kb_value == ov) 393 break; /* nothing to do */ 394 /* 395 * Attention Key. 396 */ 397 if (((ov == K_SAK) || (tmp.kb_value == K_SAK)) && 398 !capable(CAP_SYS_ADMIN)) 399 return -EPERM; 400 key_map[tmp.kb_index] = U(tmp.kb_value); 401 break; 402 } 403 return 0; 404 } 405 406 static int 407 do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs, 408 int cmd, int perm) 409 { 410 unsigned char kb_func; 411 char *p; 412 int len; 413 414 /* Get u_kbs->kb_func. */ 415 if (get_user(kb_func, &u_kbs->kb_func)) 416 return -EFAULT; 417 #if MAX_NR_FUNC < 256 418 if (kb_func >= MAX_NR_FUNC) 419 return -EINVAL; 420 #endif 421 422 switch (cmd) { 423 case KDGKBSENT: 424 p = kbd->func_table[kb_func]; 425 if (p) { 426 len = strlen(p); 427 if (len >= sizeof(u_kbs->kb_string)) 428 len = sizeof(u_kbs->kb_string) - 1; 429 if (copy_to_user(u_kbs->kb_string, p, len)) 430 return -EFAULT; 431 } else 432 len = 0; 433 if (put_user('\0', u_kbs->kb_string + len)) 434 return -EFAULT; 435 break; 436 case KDSKBSENT: 437 if (!perm) 438 return -EPERM; 439 len = strnlen_user(u_kbs->kb_string, 440 sizeof(u_kbs->kb_string) - 1); 441 if (!len) 442 return -EFAULT; 443 if (len > sizeof(u_kbs->kb_string) - 1) 444 return -EINVAL; 445 p = kmalloc(len + 1, GFP_KERNEL); 446 if (!p) 447 return -ENOMEM; 448 if (copy_from_user(p, u_kbs->kb_string, len)) { 449 kfree(p); 450 return -EFAULT; 451 } 452 p[len] = 0; 453 kfree(kbd->func_table[kb_func]); 454 kbd->func_table[kb_func] = p; 455 break; 456 } 457 return 0; 458 } 459 460 int 461 kbd_ioctl(struct kbd_data *kbd, struct file *file, 462 unsigned int cmd, unsigned long arg) 463 { 464 void __user *argp; 465 int ct, perm; 466 467 argp = (void __user *)arg; 468 469 /* 470 * To have permissions to do most of the vt ioctls, we either have 471 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG. 472 */ 473 perm = current->signal->tty == kbd->tty || capable(CAP_SYS_TTY_CONFIG); 474 switch (cmd) { 475 case KDGKBTYPE: 476 return put_user(KB_101, (char __user *)argp); 477 case KDGKBENT: 478 case KDSKBENT: 479 return do_kdsk_ioctl(kbd, argp, cmd, perm); 480 case KDGKBSENT: 481 case KDSKBSENT: 482 return do_kdgkb_ioctl(kbd, argp, cmd, perm); 483 case KDGKBDIACR: 484 { 485 struct kbdiacrs __user *a = argp; 486 struct kbdiacr diacr; 487 int i; 488 489 if (put_user(kbd->accent_table_size, &a->kb_cnt)) 490 return -EFAULT; 491 for (i = 0; i < kbd->accent_table_size; i++) { 492 diacr.diacr = kbd->accent_table[i].diacr; 493 diacr.base = kbd->accent_table[i].base; 494 diacr.result = kbd->accent_table[i].result; 495 if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) 496 return -EFAULT; 497 } 498 return 0; 499 } 500 case KDGKBDIACRUC: 501 { 502 struct kbdiacrsuc __user *a = argp; 503 504 ct = kbd->accent_table_size; 505 if (put_user(ct, &a->kb_cnt)) 506 return -EFAULT; 507 if (copy_to_user(a->kbdiacruc, kbd->accent_table, 508 ct * sizeof(struct kbdiacruc))) 509 return -EFAULT; 510 return 0; 511 } 512 case KDSKBDIACR: 513 { 514 struct kbdiacrs __user *a = argp; 515 struct kbdiacr diacr; 516 int i; 517 518 if (!perm) 519 return -EPERM; 520 if (get_user(ct, &a->kb_cnt)) 521 return -EFAULT; 522 if (ct >= MAX_DIACR) 523 return -EINVAL; 524 kbd->accent_table_size = ct; 525 for (i = 0; i < ct; i++) { 526 if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) 527 return -EFAULT; 528 kbd->accent_table[i].diacr = diacr.diacr; 529 kbd->accent_table[i].base = diacr.base; 530 kbd->accent_table[i].result = diacr.result; 531 } 532 return 0; 533 } 534 case KDSKBDIACRUC: 535 { 536 struct kbdiacrsuc __user *a = argp; 537 538 if (!perm) 539 return -EPERM; 540 if (get_user(ct, &a->kb_cnt)) 541 return -EFAULT; 542 if (ct >= MAX_DIACR) 543 return -EINVAL; 544 kbd->accent_table_size = ct; 545 if (copy_from_user(kbd->accent_table, a->kbdiacruc, 546 ct * sizeof(struct kbdiacruc))) 547 return -EFAULT; 548 return 0; 549 } 550 default: 551 return -ENOIOCTLCMD; 552 } 553 } 554 555 EXPORT_SYMBOL(kbd_ioctl); 556 EXPORT_SYMBOL(kbd_ascebc); 557 EXPORT_SYMBOL(kbd_free); 558 EXPORT_SYMBOL(kbd_alloc); 559 EXPORT_SYMBOL(kbd_keycode); 560