diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acorn/char/defkeymap-l7200.c | 2 | ||||
-rw-r--r-- | drivers/char/consolemap.c | 22 | ||||
-rw-r--r-- | drivers/char/defkeymap.c_shipped | 2 | ||||
-rw-r--r-- | drivers/char/keyboard.c | 35 | ||||
-rw-r--r-- | drivers/char/vt_ioctl.c | 46 | ||||
-rw-r--r-- | drivers/s390/char/defkeymap.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/keyboard.c | 66 | ||||
-rw-r--r-- | drivers/s390/char/keyboard.h | 4 | ||||
-rw-r--r-- | drivers/tc/lk201-map.c_shipped | 2 |
9 files changed, 146 insertions, 35 deletions
diff --git a/drivers/acorn/char/defkeymap-l7200.c b/drivers/acorn/char/defkeymap-l7200.c index 9e18ce742e38..28a5fbc6aa1a 100644 --- a/drivers/acorn/char/defkeymap-l7200.c +++ b/drivers/acorn/char/defkeymap-l7200.c | |||
@@ -346,7 +346,7 @@ char *func_table[MAX_NR_FUNC] = { | |||
346 | 0, | 346 | 0, |
347 | }; | 347 | }; |
348 | 348 | ||
349 | struct kbdiacr accent_table[MAX_DIACR] = { | 349 | struct kbdiacruc accent_table[MAX_DIACR] = { |
350 | {'`', 'A', '\300'}, {'`', 'a', '\340'}, | 350 | {'`', 'A', '\300'}, {'`', 'a', '\340'}, |
351 | {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, | 351 | {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, |
352 | {'^', 'A', '\302'}, {'^', 'a', '\342'}, | 352 | {'^', 'A', '\302'}, {'^', 'a', '\342'}, |
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c index 163f3fce3f84..6b104e45a322 100644 --- a/drivers/char/consolemap.c +++ b/drivers/char/consolemap.c | |||
@@ -669,19 +669,29 @@ void con_protect_unimap(struct vc_data *vc, int rdonly) | |||
669 | p->readonly = rdonly; | 669 | p->readonly = rdonly; |
670 | } | 670 | } |
671 | 671 | ||
672 | /* | ||
673 | * Always use USER_MAP. These functions are used by the keyboard, | ||
674 | * which shouldn't be affected by G0/G1 switching, etc. | ||
675 | * If the user map still contains default values, i.e. the | ||
676 | * direct-to-font mapping, then assume user is using Latin1. | ||
677 | */ | ||
672 | /* may be called during an interrupt */ | 678 | /* may be called during an interrupt */ |
673 | u32 conv_8bit_to_uni(unsigned char c) | 679 | u32 conv_8bit_to_uni(unsigned char c) |
674 | { | 680 | { |
675 | /* | ||
676 | * Always use USER_MAP. This function is used by the keyboard, | ||
677 | * which shouldn't be affected by G0/G1 switching, etc. | ||
678 | * If the user map still contains default values, i.e. the | ||
679 | * direct-to-font mapping, then assume user is using Latin1. | ||
680 | */ | ||
681 | unsigned short uni = translations[USER_MAP][c]; | 681 | unsigned short uni = translations[USER_MAP][c]; |
682 | return uni == (0xf000 | c) ? c : uni; | 682 | return uni == (0xf000 | c) ? c : uni; |
683 | } | 683 | } |
684 | 684 | ||
685 | int conv_uni_to_8bit(u32 uni) | ||
686 | { | ||
687 | int c; | ||
688 | for (c = 0; c < 0x100; c++) | ||
689 | if (translations[USER_MAP][c] == uni || | ||
690 | (translations[USER_MAP][c] == (c | 0xf000) && uni == c)) | ||
691 | return c; | ||
692 | return -1; | ||
693 | } | ||
694 | |||
685 | int | 695 | int |
686 | conv_uni_to_pc(struct vc_data *conp, long ucs) | 696 | conv_uni_to_pc(struct vc_data *conp, long ucs) |
687 | { | 697 | { |
diff --git a/drivers/char/defkeymap.c_shipped b/drivers/char/defkeymap.c_shipped index 453a2f1ffa15..0aa419a61767 100644 --- a/drivers/char/defkeymap.c_shipped +++ b/drivers/char/defkeymap.c_shipped | |||
@@ -222,7 +222,7 @@ char *func_table[MAX_NR_FUNC] = { | |||
222 | NULL, | 222 | NULL, |
223 | }; | 223 | }; |
224 | 224 | ||
225 | struct kbdiacr accent_table[MAX_DIACR] = { | 225 | struct kbdiacruc accent_table[MAX_DIACR] = { |
226 | {'`', 'A', '\300'}, {'`', 'a', '\340'}, | 226 | {'`', 'A', '\300'}, {'`', 'a', '\340'}, |
227 | {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, | 227 | {'\'', 'A', '\301'}, {'\'', 'a', '\341'}, |
228 | {'^', 'A', '\302'}, {'^', 'a', '\342'}, | 228 | {'^', 'A', '\302'}, {'^', 'a', '\342'}, |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index d95f316afb5a..5ae2a3250c50 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/kbd_kern.h> | 38 | #include <linux/kbd_kern.h> |
39 | #include <linux/kbd_diacr.h> | 39 | #include <linux/kbd_diacr.h> |
40 | #include <linux/vt_kern.h> | 40 | #include <linux/vt_kern.h> |
41 | #include <linux/consolemap.h> | ||
41 | #include <linux/sysrq.h> | 42 | #include <linux/sysrq.h> |
42 | #include <linux/input.h> | 43 | #include <linux/input.h> |
43 | #include <linux/reboot.h> | 44 | #include <linux/reboot.h> |
@@ -403,9 +404,12 @@ static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch) | |||
403 | return d; | 404 | return d; |
404 | 405 | ||
405 | if (kbd->kbdmode == VC_UNICODE) | 406 | if (kbd->kbdmode == VC_UNICODE) |
406 | to_utf8(vc, conv_8bit_to_uni(d)); | 407 | to_utf8(vc, d); |
407 | else if (d < 0x100) | 408 | else { |
408 | put_queue(vc, d); | 409 | int c = conv_uni_to_8bit(d); |
410 | if (c != -1) | ||
411 | put_queue(vc, c); | ||
412 | } | ||
409 | 413 | ||
410 | return ch; | 414 | return ch; |
411 | } | 415 | } |
@@ -417,9 +421,12 @@ static void fn_enter(struct vc_data *vc) | |||
417 | { | 421 | { |
418 | if (diacr) { | 422 | if (diacr) { |
419 | if (kbd->kbdmode == VC_UNICODE) | 423 | if (kbd->kbdmode == VC_UNICODE) |
420 | to_utf8(vc, conv_8bit_to_uni(diacr)); | 424 | to_utf8(vc, diacr); |
421 | else if (diacr < 0x100) | 425 | else { |
422 | put_queue(vc, diacr); | 426 | int c = conv_uni_to_8bit(diacr); |
427 | if (c != -1) | ||
428 | put_queue(vc, c); | ||
429 | } | ||
423 | diacr = 0; | 430 | diacr = 0; |
424 | } | 431 | } |
425 | put_queue(vc, 13); | 432 | put_queue(vc, 13); |
@@ -627,9 +634,12 @@ static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag) | |||
627 | return; | 634 | return; |
628 | } | 635 | } |
629 | if (kbd->kbdmode == VC_UNICODE) | 636 | if (kbd->kbdmode == VC_UNICODE) |
630 | to_utf8(vc, conv_8bit_to_uni(value)); | 637 | to_utf8(vc, value); |
631 | else if (value < 0x100) | 638 | else { |
632 | put_queue(vc, value); | 639 | int c = conv_uni_to_8bit(value); |
640 | if (c != -1) | ||
641 | put_queue(vc, c); | ||
642 | } | ||
633 | } | 643 | } |
634 | 644 | ||
635 | /* | 645 | /* |
@@ -646,7 +656,12 @@ static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag) | |||
646 | 656 | ||
647 | static void k_self(struct vc_data *vc, unsigned char value, char up_flag) | 657 | static void k_self(struct vc_data *vc, unsigned char value, char up_flag) |
648 | { | 658 | { |
649 | k_unicode(vc, value, up_flag); | 659 | unsigned int uni; |
660 | if (kbd->kbdmode == VC_UNICODE) | ||
661 | uni = value; | ||
662 | else | ||
663 | uni = conv_8bit_to_uni(value); | ||
664 | k_unicode(vc, uni, up_flag); | ||
650 | } | 665 | } |
651 | 666 | ||
652 | static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) | 667 | static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index f69a8258095c..6c7384afff13 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/major.h> | 23 | #include <linux/major.h> |
24 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
25 | #include <linux/console.h> | 25 | #include <linux/console.h> |
26 | #include <linux/consolemap.h> | ||
26 | #include <linux/signal.h> | 27 | #include <linux/signal.h> |
27 | #include <linux/timex.h> | 28 | #include <linux/timex.h> |
28 | 29 | ||
@@ -582,10 +583,27 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
582 | case KDGKBDIACR: | 583 | case KDGKBDIACR: |
583 | { | 584 | { |
584 | struct kbdiacrs __user *a = up; | 585 | struct kbdiacrs __user *a = up; |
586 | struct kbdiacr diacr; | ||
587 | int i; | ||
585 | 588 | ||
586 | if (put_user(accent_table_size, &a->kb_cnt)) | 589 | if (put_user(accent_table_size, &a->kb_cnt)) |
587 | return -EFAULT; | 590 | return -EFAULT; |
588 | if (copy_to_user(a->kbdiacr, accent_table, accent_table_size*sizeof(struct kbdiacr))) | 591 | for (i = 0; i < accent_table_size; i++) { |
592 | diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr); | ||
593 | diacr.base = conv_uni_to_8bit(accent_table[i].base); | ||
594 | diacr.result = conv_uni_to_8bit(accent_table[i].result); | ||
595 | if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) | ||
596 | return -EFAULT; | ||
597 | } | ||
598 | return 0; | ||
599 | } | ||
600 | case KDGKBDIACRUC: | ||
601 | { | ||
602 | struct kbdiacrsuc __user *a = up; | ||
603 | |||
604 | if (put_user(accent_table_size, &a->kb_cnt)) | ||
605 | return -EFAULT; | ||
606 | if (copy_to_user(a->kbdiacruc, accent_table, accent_table_size*sizeof(struct kbdiacruc))) | ||
589 | return -EFAULT; | 607 | return -EFAULT; |
590 | return 0; | 608 | return 0; |
591 | } | 609 | } |
@@ -593,6 +611,30 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
593 | case KDSKBDIACR: | 611 | case KDSKBDIACR: |
594 | { | 612 | { |
595 | struct kbdiacrs __user *a = up; | 613 | struct kbdiacrs __user *a = up; |
614 | struct kbdiacr diacr; | ||
615 | unsigned int ct; | ||
616 | int i; | ||
617 | |||
618 | if (!perm) | ||
619 | return -EPERM; | ||
620 | if (get_user(ct,&a->kb_cnt)) | ||
621 | return -EFAULT; | ||
622 | if (ct >= MAX_DIACR) | ||
623 | return -EINVAL; | ||
624 | accent_table_size = ct; | ||
625 | for (i = 0; i < ct; i++) { | ||
626 | if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) | ||
627 | return -EFAULT; | ||
628 | accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr); | ||
629 | accent_table[i].base = conv_8bit_to_uni(diacr.base); | ||
630 | accent_table[i].result = conv_8bit_to_uni(diacr.result); | ||
631 | } | ||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | case KDSKBDIACRUC: | ||
636 | { | ||
637 | struct kbdiacrsuc __user *a = up; | ||
596 | unsigned int ct; | 638 | unsigned int ct; |
597 | 639 | ||
598 | if (!perm) | 640 | if (!perm) |
@@ -602,7 +644,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
602 | if (ct >= MAX_DIACR) | 644 | if (ct >= MAX_DIACR) |
603 | return -EINVAL; | 645 | return -EINVAL; |
604 | accent_table_size = ct; | 646 | accent_table_size = ct; |
605 | if (copy_from_user(accent_table, a->kbdiacr, ct*sizeof(struct kbdiacr))) | 647 | if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc))) |
606 | return -EFAULT; | 648 | return -EFAULT; |
607 | return 0; | 649 | return 0; |
608 | } | 650 | } |
diff --git a/drivers/s390/char/defkeymap.c b/drivers/s390/char/defkeymap.c index 564baca01b7c..389346cda6c8 100644 --- a/drivers/s390/char/defkeymap.c +++ b/drivers/s390/char/defkeymap.c | |||
@@ -150,7 +150,7 @@ char *func_table[MAX_NR_FUNC] = { | |||
150 | NULL, | 150 | NULL, |
151 | }; | 151 | }; |
152 | 152 | ||
153 | struct kbdiacr accent_table[MAX_DIACR] = { | 153 | struct kbdiacruc accent_table[MAX_DIACR] = { |
154 | {'^', 'c', '\003'}, {'^', 'd', '\004'}, | 154 | {'^', 'c', '\003'}, {'^', 'd', '\004'}, |
155 | {'^', 'z', '\032'}, {'^', '\012', '\000'}, | 155 | {'^', 'z', '\032'}, {'^', '\012', '\000'}, |
156 | }; | 156 | }; |
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index f62f9a4e8950..cee4d4e42429 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
12 | #include <linux/sysrq.h> | 12 | #include <linux/sysrq.h> |
13 | 13 | ||
14 | #include <linux/consolemap.h> | ||
14 | #include <linux/kbd_kern.h> | 15 | #include <linux/kbd_kern.h> |
15 | #include <linux/kbd_diacr.h> | 16 | #include <linux/kbd_diacr.h> |
16 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
@@ -82,11 +83,11 @@ kbd_alloc(void) { | |||
82 | if (!kbd->fn_handler) | 83 | if (!kbd->fn_handler) |
83 | goto out_func; | 84 | goto out_func; |
84 | kbd->accent_table = | 85 | kbd->accent_table = |
85 | kmalloc(sizeof(struct kbdiacr)*MAX_DIACR, GFP_KERNEL); | 86 | kmalloc(sizeof(struct kbdiacruc)*MAX_DIACR, GFP_KERNEL); |
86 | if (!kbd->accent_table) | 87 | if (!kbd->accent_table) |
87 | goto out_fn_handler; | 88 | goto out_fn_handler; |
88 | memcpy(kbd->accent_table, accent_table, | 89 | memcpy(kbd->accent_table, accent_table, |
89 | sizeof(struct kbdiacr)*MAX_DIACR); | 90 | sizeof(struct kbdiacruc)*MAX_DIACR); |
90 | kbd->accent_table_size = accent_table_size; | 91 | kbd->accent_table_size = accent_table_size; |
91 | return kbd; | 92 | return kbd; |
92 | 93 | ||
@@ -183,8 +184,8 @@ kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc) | |||
183 | * Otherwise, conclude that DIACR was not combining after all, | 184 | * Otherwise, conclude that DIACR was not combining after all, |
184 | * queue it and return CH. | 185 | * queue it and return CH. |
185 | */ | 186 | */ |
186 | static unsigned char | 187 | static unsigned int |
187 | handle_diacr(struct kbd_data *kbd, unsigned char ch) | 188 | handle_diacr(struct kbd_data *kbd, unsigned int ch) |
188 | { | 189 | { |
189 | int i, d; | 190 | int i, d; |
190 | 191 | ||
@@ -460,7 +461,6 @@ int | |||
460 | kbd_ioctl(struct kbd_data *kbd, struct file *file, | 461 | kbd_ioctl(struct kbd_data *kbd, struct file *file, |
461 | unsigned int cmd, unsigned long arg) | 462 | unsigned int cmd, unsigned long arg) |
462 | { | 463 | { |
463 | struct kbdiacrs __user *a; | ||
464 | void __user *argp; | 464 | void __user *argp; |
465 | int ct, perm; | 465 | int ct, perm; |
466 | 466 | ||
@@ -481,17 +481,40 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file, | |||
481 | case KDSKBSENT: | 481 | case KDSKBSENT: |
482 | return do_kdgkb_ioctl(kbd, argp, cmd, perm); | 482 | return do_kdgkb_ioctl(kbd, argp, cmd, perm); |
483 | case KDGKBDIACR: | 483 | case KDGKBDIACR: |
484 | a = argp; | 484 | { |
485 | struct kbdiacrs __user *a = argp; | ||
486 | struct kbdiacr diacr; | ||
487 | int i; | ||
485 | 488 | ||
486 | if (put_user(kbd->accent_table_size, &a->kb_cnt)) | 489 | if (put_user(kbd->accent_table_size, &a->kb_cnt)) |
487 | return -EFAULT; | 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 | |||
488 | ct = kbd->accent_table_size; | 504 | ct = kbd->accent_table_size; |
489 | if (copy_to_user(a->kbdiacr, kbd->accent_table, | 505 | if (put_user(ct, &a->kb_cnt)) |
490 | ct * sizeof(struct kbdiacr))) | 506 | return -EFAULT; |
507 | if (copy_to_user(a->kbdiacruc, kbd->accent_table, | ||
508 | ct * sizeof(struct kbdiacruc))) | ||
491 | return -EFAULT; | 509 | return -EFAULT; |
492 | return 0; | 510 | return 0; |
511 | } | ||
493 | case KDSKBDIACR: | 512 | case KDSKBDIACR: |
494 | a = argp; | 513 | { |
514 | struct kbdiacrs __user *a = argp; | ||
515 | struct kbdiacr diacr; | ||
516 | int i; | ||
517 | |||
495 | if (!perm) | 518 | if (!perm) |
496 | return -EPERM; | 519 | return -EPERM; |
497 | if (get_user(ct, &a->kb_cnt)) | 520 | if (get_user(ct, &a->kb_cnt)) |
@@ -499,10 +522,31 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file, | |||
499 | if (ct >= MAX_DIACR) | 522 | if (ct >= MAX_DIACR) |
500 | return -EINVAL; | 523 | return -EINVAL; |
501 | kbd->accent_table_size = ct; | 524 | kbd->accent_table_size = ct; |
502 | if (copy_from_user(kbd->accent_table, a->kbdiacr, | 525 | for (i = 0; i < ct; i++) { |
503 | ct * sizeof(struct kbdiacr))) | 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))) | ||
504 | return -EFAULT; | 547 | return -EFAULT; |
505 | return 0; | 548 | return 0; |
549 | } | ||
506 | default: | 550 | default: |
507 | return -ENOIOCTLCMD; | 551 | return -ENOIOCTLCMD; |
508 | } | 552 | } |
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h index f7bf45c6bf0d..5ccfe9cf126d 100644 --- a/drivers/s390/char/keyboard.h +++ b/drivers/s390/char/keyboard.h | |||
@@ -25,9 +25,9 @@ struct kbd_data { | |||
25 | unsigned short **key_maps; | 25 | unsigned short **key_maps; |
26 | char **func_table; | 26 | char **func_table; |
27 | fn_handler_fn **fn_handler; | 27 | fn_handler_fn **fn_handler; |
28 | struct kbdiacr *accent_table; | 28 | struct kbdiacruc *accent_table; |
29 | unsigned int accent_table_size; | 29 | unsigned int accent_table_size; |
30 | unsigned char diacr; | 30 | unsigned int diacr; |
31 | unsigned short sysrq; | 31 | unsigned short sysrq; |
32 | }; | 32 | }; |
33 | 33 | ||
diff --git a/drivers/tc/lk201-map.c_shipped b/drivers/tc/lk201-map.c_shipped index a9df8f5bf62b..4d2aba597343 100644 --- a/drivers/tc/lk201-map.c_shipped +++ b/drivers/tc/lk201-map.c_shipped | |||
@@ -225,7 +225,7 @@ char *func_table[MAX_NR_FUNC] = { | |||
225 | 0, | 225 | 0, |
226 | }; | 226 | }; |
227 | 227 | ||
228 | struct kbdiacr accent_table[MAX_DIACR] = { | 228 | struct kbdiacruc accent_table[MAX_DIACR] = { |
229 | {'`', 'A', 'À'}, {'`', 'a', 'à'}, | 229 | {'`', 'A', 'À'}, {'`', 'a', 'à'}, |
230 | {'\'', 'A', 'Á'}, {'\'', 'a', 'á'}, | 230 | {'\'', 'A', 'Á'}, {'\'', 'a', 'á'}, |
231 | {'^', 'A', 'Â'}, {'^', 'a', 'â'}, | 231 | {'^', 'A', 'Â'}, {'^', 'a', 'â'}, |