diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-10 18:54:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-10 18:54:41 -0400 |
commit | 7f93220b624de1b7d9fcff8a2cebd6fce7ed4665 (patch) | |
tree | 5070ec25635008082b47a646d64b4359896c0faa /drivers/char | |
parent | 2b8dfec8c8fa4ba5bc946a602e94e99861462cad (diff) | |
parent | d39969deee4b541be4ee5789a2e4c14511c886e2 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/keyboard.c | 111 |
1 files changed, 56 insertions, 55 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 1745065d8f78..449d029ad4f4 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -14,7 +14,7 @@ | |||
14 | * `Sticky' modifier keys, 951006. | 14 | * `Sticky' modifier keys, 951006. |
15 | * | 15 | * |
16 | * 11-11-96: SAK should now work in the raw mode (Martin Mares) | 16 | * 11-11-96: SAK should now work in the raw mode (Martin Mares) |
17 | * | 17 | * |
18 | * Modified to provide 'generic' keyboard support by Hamish Macdonald | 18 | * Modified to provide 'generic' keyboard support by Hamish Macdonald |
19 | * Merge with the m68k keyboard driver and split-off of the PC low-level | 19 | * Merge with the m68k keyboard driver and split-off of the PC low-level |
20 | * parts by Geert Uytterhoeven, May 1997 | 20 | * parts by Geert Uytterhoeven, May 1997 |
@@ -52,7 +52,7 @@ extern void ctrl_alt_del(void); | |||
52 | /* | 52 | /* |
53 | * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on. | 53 | * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on. |
54 | * This seems a good reason to start with NumLock off. On HIL keyboards | 54 | * This seems a good reason to start with NumLock off. On HIL keyboards |
55 | * of PARISC machines however there is no NumLock key and everyone expects the keypad | 55 | * of PARISC machines however there is no NumLock key and everyone expects the keypad |
56 | * to be used for numbers. | 56 | * to be used for numbers. |
57 | */ | 57 | */ |
58 | 58 | ||
@@ -76,17 +76,17 @@ void compute_shiftstate(void); | |||
76 | k_meta, k_ascii, k_lock, k_lowercase,\ | 76 | k_meta, k_ascii, k_lock, k_lowercase,\ |
77 | k_slock, k_dead2, k_ignore, k_ignore | 77 | k_slock, k_dead2, k_ignore, k_ignore |
78 | 78 | ||
79 | typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value, | 79 | typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value, |
80 | char up_flag, struct pt_regs *regs); | 80 | char up_flag, struct pt_regs *regs); |
81 | static k_handler_fn K_HANDLERS; | 81 | static k_handler_fn K_HANDLERS; |
82 | static k_handler_fn *k_handler[16] = { K_HANDLERS }; | 82 | static k_handler_fn *k_handler[16] = { K_HANDLERS }; |
83 | 83 | ||
84 | #define FN_HANDLERS\ | 84 | #define FN_HANDLERS\ |
85 | fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\ | 85 | fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\ |
86 | fn_show_state, fn_send_intr, fn_lastcons, fn_caps_toggle,\ | 86 | fn_show_state, fn_send_intr, fn_lastcons, fn_caps_toggle,\ |
87 | fn_num, fn_hold, fn_scroll_forw, fn_scroll_back,\ | 87 | fn_num, fn_hold, fn_scroll_forw, fn_scroll_back,\ |
88 | fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\ | 88 | fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\ |
89 | fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num | 89 | fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num |
90 | 90 | ||
91 | typedef void (fn_handler_fn)(struct vc_data *vc, struct pt_regs *regs); | 91 | typedef void (fn_handler_fn)(struct vc_data *vc, struct pt_regs *regs); |
92 | static fn_handler_fn FN_HANDLERS; | 92 | static fn_handler_fn FN_HANDLERS; |
@@ -159,13 +159,13 @@ static int sysrq_alt; | |||
159 | */ | 159 | */ |
160 | int getkeycode(unsigned int scancode) | 160 | int getkeycode(unsigned int scancode) |
161 | { | 161 | { |
162 | struct list_head * node; | 162 | struct list_head *node; |
163 | struct input_dev *dev = NULL; | 163 | struct input_dev *dev = NULL; |
164 | 164 | ||
165 | list_for_each(node,&kbd_handler.h_list) { | 165 | list_for_each(node, &kbd_handler.h_list) { |
166 | struct input_handle * handle = to_handle_h(node); | 166 | struct input_handle *handle = to_handle_h(node); |
167 | if (handle->dev->keycodesize) { | 167 | if (handle->dev->keycodesize) { |
168 | dev = handle->dev; | 168 | dev = handle->dev; |
169 | break; | 169 | break; |
170 | } | 170 | } |
171 | } | 171 | } |
@@ -181,15 +181,15 @@ int getkeycode(unsigned int scancode) | |||
181 | 181 | ||
182 | int setkeycode(unsigned int scancode, unsigned int keycode) | 182 | int setkeycode(unsigned int scancode, unsigned int keycode) |
183 | { | 183 | { |
184 | struct list_head * node; | 184 | struct list_head *node; |
185 | struct input_dev *dev = NULL; | 185 | struct input_dev *dev = NULL; |
186 | unsigned int i, oldkey; | 186 | unsigned int i, oldkey; |
187 | 187 | ||
188 | list_for_each(node,&kbd_handler.h_list) { | 188 | list_for_each(node, &kbd_handler.h_list) { |
189 | struct input_handle *handle = to_handle_h(node); | 189 | struct input_handle *handle = to_handle_h(node); |
190 | if (handle->dev->keycodesize) { | 190 | if (handle->dev->keycodesize) { |
191 | dev = handle->dev; | 191 | dev = handle->dev; |
192 | break; | 192 | break; |
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
@@ -200,7 +200,7 @@ int setkeycode(unsigned int scancode, unsigned int keycode) | |||
200 | return -EINVAL; | 200 | return -EINVAL; |
201 | if (keycode < 0 || keycode > KEY_MAX) | 201 | if (keycode < 0 || keycode > KEY_MAX) |
202 | return -EINVAL; | 202 | return -EINVAL; |
203 | if (keycode >> (dev->keycodesize * 8)) | 203 | if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) |
204 | return -EINVAL; | 204 | return -EINVAL; |
205 | 205 | ||
206 | oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode); | 206 | oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode); |
@@ -216,11 +216,11 @@ int setkeycode(unsigned int scancode, unsigned int keycode) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | /* | 218 | /* |
219 | * Making beeps and bells. | 219 | * Making beeps and bells. |
220 | */ | 220 | */ |
221 | static void kd_nosound(unsigned long ignored) | 221 | static void kd_nosound(unsigned long ignored) |
222 | { | 222 | { |
223 | struct list_head * node; | 223 | struct list_head *node; |
224 | 224 | ||
225 | list_for_each(node,&kbd_handler.h_list) { | 225 | list_for_each(node,&kbd_handler.h_list) { |
226 | struct input_handle *handle = to_handle_h(node); | 226 | struct input_handle *handle = to_handle_h(node); |
@@ -237,12 +237,12 @@ static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0); | |||
237 | 237 | ||
238 | void kd_mksound(unsigned int hz, unsigned int ticks) | 238 | void kd_mksound(unsigned int hz, unsigned int ticks) |
239 | { | 239 | { |
240 | struct list_head * node; | 240 | struct list_head *node; |
241 | 241 | ||
242 | del_timer(&kd_mksound_timer); | 242 | del_timer(&kd_mksound_timer); |
243 | 243 | ||
244 | if (hz) { | 244 | if (hz) { |
245 | list_for_each_prev(node,&kbd_handler.h_list) { | 245 | list_for_each_prev(node, &kbd_handler.h_list) { |
246 | struct input_handle *handle = to_handle_h(node); | 246 | struct input_handle *handle = to_handle_h(node); |
247 | if (test_bit(EV_SND, handle->dev->evbit)) { | 247 | if (test_bit(EV_SND, handle->dev->evbit)) { |
248 | if (test_bit(SND_TONE, handle->dev->sndbit)) { | 248 | if (test_bit(SND_TONE, handle->dev->sndbit)) { |
@@ -337,19 +337,19 @@ static void to_utf8(struct vc_data *vc, ushort c) | |||
337 | if (c < 0x80) | 337 | if (c < 0x80) |
338 | /* 0******* */ | 338 | /* 0******* */ |
339 | put_queue(vc, c); | 339 | put_queue(vc, c); |
340 | else if (c < 0x800) { | 340 | else if (c < 0x800) { |
341 | /* 110***** 10****** */ | 341 | /* 110***** 10****** */ |
342 | put_queue(vc, 0xc0 | (c >> 6)); | 342 | put_queue(vc, 0xc0 | (c >> 6)); |
343 | put_queue(vc, 0x80 | (c & 0x3f)); | 343 | put_queue(vc, 0x80 | (c & 0x3f)); |
344 | } else { | 344 | } else { |
345 | /* 1110**** 10****** 10****** */ | 345 | /* 1110**** 10****** 10****** */ |
346 | put_queue(vc, 0xe0 | (c >> 12)); | 346 | put_queue(vc, 0xe0 | (c >> 12)); |
347 | put_queue(vc, 0x80 | ((c >> 6) & 0x3f)); | 347 | put_queue(vc, 0x80 | ((c >> 6) & 0x3f)); |
348 | put_queue(vc, 0x80 | (c & 0x3f)); | 348 | put_queue(vc, 0x80 | (c & 0x3f)); |
349 | } | 349 | } |
350 | } | 350 | } |
351 | 351 | ||
352 | /* | 352 | /* |
353 | * Called after returning from RAW mode or when changing consoles - recompute | 353 | * Called after returning from RAW mode or when changing consoles - recompute |
354 | * shift_down[] and shift_state from key_down[] maybe called when keymap is | 354 | * shift_down[] and shift_state from key_down[] maybe called when keymap is |
355 | * undefined, so that shiftkey release is seen | 355 | * undefined, so that shiftkey release is seen |
@@ -360,7 +360,7 @@ void compute_shiftstate(void) | |||
360 | 360 | ||
361 | shift_state = 0; | 361 | shift_state = 0; |
362 | memset(shift_down, 0, sizeof(shift_down)); | 362 | memset(shift_down, 0, sizeof(shift_down)); |
363 | 363 | ||
364 | for (i = 0; i < ARRAY_SIZE(key_down); i++) { | 364 | for (i = 0; i < ARRAY_SIZE(key_down); i++) { |
365 | 365 | ||
366 | if (!key_down[i]) | 366 | if (!key_down[i]) |
@@ -499,9 +499,9 @@ static void fn_dec_console(struct vc_data *vc, struct pt_regs *regs) | |||
499 | if (want_console != -1) | 499 | if (want_console != -1) |
500 | cur = want_console; | 500 | cur = want_console; |
501 | 501 | ||
502 | for (i = cur-1; i != cur; i--) { | 502 | for (i = cur - 1; i != cur; i--) { |
503 | if (i == -1) | 503 | if (i == -1) |
504 | i = MAX_NR_CONSOLES-1; | 504 | i = MAX_NR_CONSOLES - 1; |
505 | if (vc_cons_allocated(i)) | 505 | if (vc_cons_allocated(i)) |
506 | break; | 506 | break; |
507 | } | 507 | } |
@@ -567,9 +567,9 @@ static void fn_compose(struct vc_data *vc, struct pt_regs *regs) | |||
567 | 567 | ||
568 | static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs) | 568 | static void fn_spawn_con(struct vc_data *vc, struct pt_regs *regs) |
569 | { | 569 | { |
570 | if (spawnpid) | 570 | if (spawnpid) |
571 | if(kill_proc(spawnpid, spawnsig, 1)) | 571 | if (kill_proc(spawnpid, spawnsig, 1)) |
572 | spawnpid = 0; | 572 | spawnpid = 0; |
573 | } | 573 | } |
574 | 574 | ||
575 | static void fn_SAK(struct vc_data *vc, struct pt_regs *regs) | 575 | static void fn_SAK(struct vc_data *vc, struct pt_regs *regs) |
@@ -603,8 +603,8 @@ static void k_spec(struct vc_data *vc, unsigned char value, char up_flag, struct | |||
603 | return; | 603 | return; |
604 | if (value >= ARRAY_SIZE(fn_handler)) | 604 | if (value >= ARRAY_SIZE(fn_handler)) |
605 | return; | 605 | return; |
606 | if ((kbd->kbdmode == VC_RAW || | 606 | if ((kbd->kbdmode == VC_RAW || |
607 | kbd->kbdmode == VC_MEDIUMRAW) && | 607 | kbd->kbdmode == VC_MEDIUMRAW) && |
608 | value != KVAL(K_SAK)) | 608 | value != KVAL(K_SAK)) |
609 | return; /* SAK is allowed even in raw mode */ | 609 | return; /* SAK is allowed even in raw mode */ |
610 | fn_handler[value](vc, regs); | 610 | fn_handler[value](vc, regs); |
@@ -894,11 +894,11 @@ static inline unsigned char getleds(void) | |||
894 | 894 | ||
895 | static void kbd_bh(unsigned long dummy) | 895 | static void kbd_bh(unsigned long dummy) |
896 | { | 896 | { |
897 | struct list_head * node; | 897 | struct list_head *node; |
898 | unsigned char leds = getleds(); | 898 | unsigned char leds = getleds(); |
899 | 899 | ||
900 | if (leds != ledstate) { | 900 | if (leds != ledstate) { |
901 | list_for_each(node,&kbd_handler.h_list) { | 901 | list_for_each(node, &kbd_handler.h_list) { |
902 | struct input_handle * handle = to_handle_h(node); | 902 | struct input_handle * handle = to_handle_h(node); |
903 | input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | 903 | input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); |
904 | input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); | 904 | input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); |
@@ -963,11 +963,11 @@ static int sparc_l1_a_state = 0; | |||
963 | extern void sun_do_break(void); | 963 | extern void sun_do_break(void); |
964 | #endif | 964 | #endif |
965 | 965 | ||
966 | static int emulate_raw(struct vc_data *vc, unsigned int keycode, | 966 | static int emulate_raw(struct vc_data *vc, unsigned int keycode, |
967 | unsigned char up_flag) | 967 | unsigned char up_flag) |
968 | { | 968 | { |
969 | if (keycode > 255 || !x86_keycodes[keycode]) | 969 | if (keycode > 255 || !x86_keycodes[keycode]) |
970 | return -1; | 970 | return -1; |
971 | 971 | ||
972 | switch (keycode) { | 972 | switch (keycode) { |
973 | case KEY_PAUSE: | 973 | case KEY_PAUSE: |
@@ -981,7 +981,7 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, | |||
981 | case KEY_HANJA: | 981 | case KEY_HANJA: |
982 | if (!up_flag) put_queue(vc, 0xf2); | 982 | if (!up_flag) put_queue(vc, 0xf2); |
983 | return 0; | 983 | return 0; |
984 | } | 984 | } |
985 | 985 | ||
986 | if (keycode == KEY_SYSRQ && sysrq_alt) { | 986 | if (keycode == KEY_SYSRQ && sysrq_alt) { |
987 | put_queue(vc, 0x54 | up_flag); | 987 | put_queue(vc, 0x54 | up_flag); |
@@ -1104,11 +1104,12 @@ static void kbd_keycode(unsigned int keycode, int down, | |||
1104 | else | 1104 | else |
1105 | clear_bit(keycode, key_down); | 1105 | clear_bit(keycode, key_down); |
1106 | 1106 | ||
1107 | if (rep && (!vc_kbd_mode(kbd, VC_REPEAT) || (tty && | 1107 | if (rep && |
1108 | (!L_ECHO(tty) && tty->driver->chars_in_buffer(tty))))) { | 1108 | (!vc_kbd_mode(kbd, VC_REPEAT) || |
1109 | (tty && !L_ECHO(tty) && tty->driver->chars_in_buffer(tty)))) { | ||
1109 | /* | 1110 | /* |
1110 | * Don't repeat a key if the input buffers are not empty and the | 1111 | * Don't repeat a key if the input buffers are not empty and the |
1111 | * characters get aren't echoed locally. This makes key repeat | 1112 | * characters get aren't echoed locally. This makes key repeat |
1112 | * usable with slow applications and under heavy loads. | 1113 | * usable with slow applications and under heavy loads. |
1113 | */ | 1114 | */ |
1114 | return; | 1115 | return; |
@@ -1130,7 +1131,8 @@ static void kbd_keycode(unsigned int keycode, int down, | |||
1130 | type = KTYP(keysym); | 1131 | type = KTYP(keysym); |
1131 | 1132 | ||
1132 | if (type < 0xf0) { | 1133 | if (type < 0xf0) { |
1133 | if (down && !raw_mode) to_utf8(vc, keysym); | 1134 | if (down && !raw_mode) |
1135 | to_utf8(vc, keysym); | ||
1134 | return; | 1136 | return; |
1135 | } | 1137 | } |
1136 | 1138 | ||
@@ -1154,7 +1156,7 @@ static void kbd_keycode(unsigned int keycode, int down, | |||
1154 | kbd->slockstate = 0; | 1156 | kbd->slockstate = 0; |
1155 | } | 1157 | } |
1156 | 1158 | ||
1157 | static void kbd_event(struct input_handle *handle, unsigned int event_type, | 1159 | static void kbd_event(struct input_handle *handle, unsigned int event_type, |
1158 | unsigned int event_code, int value) | 1160 | unsigned int event_code, int value) |
1159 | { | 1161 | { |
1160 | if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev)) | 1162 | if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev)) |
@@ -1166,15 +1168,13 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type, | |||
1166 | schedule_console_callback(); | 1168 | schedule_console_callback(); |
1167 | } | 1169 | } |
1168 | 1170 | ||
1169 | static char kbd_name[] = "kbd"; | ||
1170 | |||
1171 | /* | 1171 | /* |
1172 | * When a keyboard (or other input device) is found, the kbd_connect | 1172 | * When a keyboard (or other input device) is found, the kbd_connect |
1173 | * function is called. The function then looks at the device, and if it | 1173 | * function is called. The function then looks at the device, and if it |
1174 | * likes it, it can open it and get events from it. In this (kbd_connect) | 1174 | * likes it, it can open it and get events from it. In this (kbd_connect) |
1175 | * function, we should decide which VT to bind that keyboard to initially. | 1175 | * function, we should decide which VT to bind that keyboard to initially. |
1176 | */ | 1176 | */ |
1177 | static struct input_handle *kbd_connect(struct input_handler *handler, | 1177 | static struct input_handle *kbd_connect(struct input_handler *handler, |
1178 | struct input_dev *dev, | 1178 | struct input_dev *dev, |
1179 | struct input_device_id *id) | 1179 | struct input_device_id *id) |
1180 | { | 1180 | { |
@@ -1182,18 +1182,19 @@ static struct input_handle *kbd_connect(struct input_handler *handler, | |||
1182 | int i; | 1182 | int i; |
1183 | 1183 | ||
1184 | for (i = KEY_RESERVED; i < BTN_MISC; i++) | 1184 | for (i = KEY_RESERVED; i < BTN_MISC; i++) |
1185 | if (test_bit(i, dev->keybit)) break; | 1185 | if (test_bit(i, dev->keybit)) |
1186 | break; | ||
1186 | 1187 | ||
1187 | if ((i == BTN_MISC) && !test_bit(EV_SND, dev->evbit)) | 1188 | if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) |
1188 | return NULL; | 1189 | return NULL; |
1189 | 1190 | ||
1190 | if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL))) | 1191 | if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL))) |
1191 | return NULL; | 1192 | return NULL; |
1192 | memset(handle, 0, sizeof(struct input_handle)); | 1193 | memset(handle, 0, sizeof(struct input_handle)); |
1193 | 1194 | ||
1194 | handle->dev = dev; | 1195 | handle->dev = dev; |
1195 | handle->handler = handler; | 1196 | handle->handler = handler; |
1196 | handle->name = kbd_name; | 1197 | handle->name = "kbd"; |
1197 | 1198 | ||
1198 | input_open_device(handle); | 1199 | input_open_device(handle); |
1199 | kbd_refresh_leds(handle); | 1200 | kbd_refresh_leds(handle); |
@@ -1212,11 +1213,11 @@ static struct input_device_id kbd_ids[] = { | |||
1212 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | 1213 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, |
1213 | .evbit = { BIT(EV_KEY) }, | 1214 | .evbit = { BIT(EV_KEY) }, |
1214 | }, | 1215 | }, |
1215 | 1216 | ||
1216 | { | 1217 | { |
1217 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | 1218 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, |
1218 | .evbit = { BIT(EV_SND) }, | 1219 | .evbit = { BIT(EV_SND) }, |
1219 | }, | 1220 | }, |
1220 | 1221 | ||
1221 | { }, /* Terminating entry */ | 1222 | { }, /* Terminating entry */ |
1222 | }; | 1223 | }; |