diff options
-rw-r--r-- | drivers/char/keyboard.c | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 1120586619ab..30a745428a09 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -1025,7 +1025,7 @@ static const unsigned short x86_keycodes[256] = | |||
1025 | 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, | 1025 | 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, |
1026 | 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, | 1026 | 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, |
1027 | 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92, | 1027 | 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92, |
1028 | 284,285,309,298,312, 91,327,328,329,331,333,335,336,337,338,339, | 1028 | 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339, |
1029 | 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349, | 1029 | 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349, |
1030 | 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355, | 1030 | 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355, |
1031 | 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361, | 1031 | 103,104,105,275,287,279,306,106,274,107,294,364,358,363,362,361, |
@@ -1047,38 +1047,55 @@ extern void sun_do_break(void); | |||
1047 | static int emulate_raw(struct vc_data *vc, unsigned int keycode, | 1047 | static int emulate_raw(struct vc_data *vc, unsigned int keycode, |
1048 | unsigned char up_flag) | 1048 | unsigned char up_flag) |
1049 | { | 1049 | { |
1050 | if (keycode > 255 || !x86_keycodes[keycode]) | 1050 | int code; |
1051 | return -1; | ||
1052 | 1051 | ||
1053 | switch (keycode) { | 1052 | switch (keycode) { |
1054 | case KEY_PAUSE: | 1053 | case KEY_PAUSE: |
1055 | put_queue(vc, 0xe1); | 1054 | put_queue(vc, 0xe1); |
1056 | put_queue(vc, 0x1d | up_flag); | 1055 | put_queue(vc, 0x1d | up_flag); |
1057 | put_queue(vc, 0x45 | up_flag); | 1056 | put_queue(vc, 0x45 | up_flag); |
1058 | return 0; | 1057 | break; |
1058 | |||
1059 | case KEY_HANGEUL: | 1059 | case KEY_HANGEUL: |
1060 | if (!up_flag) | 1060 | if (!up_flag) |
1061 | put_queue(vc, 0xf2); | 1061 | put_queue(vc, 0xf2); |
1062 | return 0; | 1062 | break; |
1063 | |||
1063 | case KEY_HANJA: | 1064 | case KEY_HANJA: |
1064 | if (!up_flag) | 1065 | if (!up_flag) |
1065 | put_queue(vc, 0xf1); | 1066 | put_queue(vc, 0xf1); |
1066 | return 0; | 1067 | break; |
1067 | } | ||
1068 | 1068 | ||
1069 | if (keycode == KEY_SYSRQ && sysrq_alt) { | 1069 | case KEY_SYSRQ: |
1070 | put_queue(vc, 0x54 | up_flag); | 1070 | /* |
1071 | return 0; | 1071 | * Real AT keyboards (that's what we're trying |
1072 | } | 1072 | * to emulate here emit 0xe0 0x2a 0xe0 0x37 when |
1073 | * pressing PrtSc/SysRq alone, but simply 0x54 | ||
1074 | * when pressing Alt+PrtSc/SysRq. | ||
1075 | */ | ||
1076 | if (sysrq_alt) { | ||
1077 | put_queue(vc, 0x54 | up_flag); | ||
1078 | } else { | ||
1079 | put_queue(vc, 0xe0); | ||
1080 | put_queue(vc, 0x2a | up_flag); | ||
1081 | put_queue(vc, 0xe0); | ||
1082 | put_queue(vc, 0x37 | up_flag); | ||
1083 | } | ||
1084 | break; | ||
1085 | |||
1086 | default: | ||
1087 | if (keycode > 255) | ||
1088 | return -1; | ||
1073 | 1089 | ||
1074 | if (x86_keycodes[keycode] & 0x100) | 1090 | code = x86_keycodes[keycode]; |
1075 | put_queue(vc, 0xe0); | 1091 | if (!code) |
1092 | return -1; | ||
1076 | 1093 | ||
1077 | put_queue(vc, (x86_keycodes[keycode] & 0x7f) | up_flag); | 1094 | if (code & 0x100) |
1095 | put_queue(vc, 0xe0); | ||
1096 | put_queue(vc, (code & 0x7f) | up_flag); | ||
1078 | 1097 | ||
1079 | if (keycode == KEY_SYSRQ) { | 1098 | break; |
1080 | put_queue(vc, 0xe0); | ||
1081 | put_queue(vc, 0x37 | up_flag); | ||
1082 | } | 1099 | } |
1083 | 1100 | ||
1084 | return 0; | 1101 | return 0; |