aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-08-06 12:12:49 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-08-06 12:12:49 -0400
commit6e1e63259b1e01f047796e7985d960ca040993e6 (patch)
tree43c895798f3f8565a34c61a0a7fa593c6900d74c /drivers/char
parenta05ef8bfdc03c5061f44d91826caa855b0aae481 (diff)
parent2ffc1ccad85e8c2e81a6a4beb390fb4ce143256b (diff)
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/dtor/input: (24 commits) Input: ati_remote - use msec instead of jiffies Input: ati_remote - add missing input_sync() Input: ati_remote - relax permissions sysfs module parameters Input: ati_remote - make filter time a module parameter Input: atkbd - restore repeat rate when resuming Input: trackpoint - activate protocol when resuming Input: logips2pp - fix button mapping for MX300 Input: keyboard - change to use kzalloc Input: serio/gameport - check whether driver core calls succeeded Input: spaceball - make 4000FLX Lefty work Input: keyboard - simplify emulate_raw() implementation Input: keyboard - remove static variable and clean up initialization Input: hiddev - use standard list implementation Input: add missing handler->start() call Input: HID - fix potential out-of-bound array access Input: fix list iteration in input_release_device() Input: iforce - add Trust Force Feedback Race Master support Input: iforce - check array bounds before accessing elements Input: libps2 - warn instead of oopsing when passed bad arguments Input: fm801-gp - fix use after free ...
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/keyboard.c139
1 files changed, 78 insertions, 61 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 056ebe84b81d..3e90aac37510 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -107,7 +107,6 @@ const int NR_TYPES = ARRAY_SIZE(max_vals);
107 107
108struct kbd_struct kbd_table[MAX_NR_CONSOLES]; 108struct kbd_struct kbd_table[MAX_NR_CONSOLES];
109static struct kbd_struct *kbd = kbd_table; 109static struct kbd_struct *kbd = kbd_table;
110static struct kbd_struct kbd0;
111 110
112int spawnpid, spawnsig; 111int spawnpid, spawnsig;
113 112
@@ -223,13 +222,13 @@ static void kd_nosound(unsigned long ignored)
223{ 222{
224 struct list_head *node; 223 struct list_head *node;
225 224
226 list_for_each(node,&kbd_handler.h_list) { 225 list_for_each(node, &kbd_handler.h_list) {
227 struct input_handle *handle = to_handle_h(node); 226 struct input_handle *handle = to_handle_h(node);
228 if (test_bit(EV_SND, handle->dev->evbit)) { 227 if (test_bit(EV_SND, handle->dev->evbit)) {
229 if (test_bit(SND_TONE, handle->dev->sndbit)) 228 if (test_bit(SND_TONE, handle->dev->sndbit))
230 input_event(handle->dev, EV_SND, SND_TONE, 0); 229 input_inject_event(handle, EV_SND, SND_TONE, 0);
231 if (test_bit(SND_BELL, handle->dev->sndbit)) 230 if (test_bit(SND_BELL, handle->dev->sndbit))
232 input_event(handle->dev, EV_SND, SND_BELL, 0); 231 input_inject_event(handle, EV_SND, SND_BELL, 0);
233 } 232 }
234 } 233 }
235} 234}
@@ -247,11 +246,11 @@ void kd_mksound(unsigned int hz, unsigned int ticks)
247 struct input_handle *handle = to_handle_h(node); 246 struct input_handle *handle = to_handle_h(node);
248 if (test_bit(EV_SND, handle->dev->evbit)) { 247 if (test_bit(EV_SND, handle->dev->evbit)) {
249 if (test_bit(SND_TONE, handle->dev->sndbit)) { 248 if (test_bit(SND_TONE, handle->dev->sndbit)) {
250 input_event(handle->dev, EV_SND, SND_TONE, hz); 249 input_inject_event(handle, EV_SND, SND_TONE, hz);
251 break; 250 break;
252 } 251 }
253 if (test_bit(SND_BELL, handle->dev->sndbit)) { 252 if (test_bit(SND_BELL, handle->dev->sndbit)) {
254 input_event(handle->dev, EV_SND, SND_BELL, 1); 253 input_inject_event(handle, EV_SND, SND_BELL, 1);
255 break; 254 break;
256 } 255 }
257 } 256 }
@@ -272,15 +271,15 @@ int kbd_rate(struct kbd_repeat *rep)
272 unsigned int d = 0; 271 unsigned int d = 0;
273 unsigned int p = 0; 272 unsigned int p = 0;
274 273
275 list_for_each(node,&kbd_handler.h_list) { 274 list_for_each(node, &kbd_handler.h_list) {
276 struct input_handle *handle = to_handle_h(node); 275 struct input_handle *handle = to_handle_h(node);
277 struct input_dev *dev = handle->dev; 276 struct input_dev *dev = handle->dev;
278 277
279 if (test_bit(EV_REP, dev->evbit)) { 278 if (test_bit(EV_REP, dev->evbit)) {
280 if (rep->delay > 0) 279 if (rep->delay > 0)
281 input_event(dev, EV_REP, REP_DELAY, rep->delay); 280 input_inject_event(handle, EV_REP, REP_DELAY, rep->delay);
282 if (rep->period > 0) 281 if (rep->period > 0)
283 input_event(dev, EV_REP, REP_PERIOD, rep->period); 282 input_inject_event(handle, EV_REP, REP_PERIOD, rep->period);
284 d = dev->rep[REP_DELAY]; 283 d = dev->rep[REP_DELAY];
285 p = dev->rep[REP_PERIOD]; 284 p = dev->rep[REP_PERIOD];
286 } 285 }
@@ -988,7 +987,7 @@ static inline unsigned char getleds(void)
988 * interrupt routines for this thing allows us to easily mask 987 * interrupt routines for this thing allows us to easily mask
989 * this when we don't want any of the above to happen. 988 * this when we don't want any of the above to happen.
990 * This allows for easy and efficient race-condition prevention 989 * This allows for easy and efficient race-condition prevention
991 * for kbd_refresh_leds => input_event(dev, EV_LED, ...) => ... 990 * for kbd_start => input_inject_event(dev, EV_LED, ...) => ...
992 */ 991 */
993 992
994static void kbd_bh(unsigned long dummy) 993static void kbd_bh(unsigned long dummy)
@@ -998,11 +997,11 @@ static void kbd_bh(unsigned long dummy)
998 997
999 if (leds != ledstate) { 998 if (leds != ledstate) {
1000 list_for_each(node, &kbd_handler.h_list) { 999 list_for_each(node, &kbd_handler.h_list) {
1001 struct input_handle * handle = to_handle_h(node); 1000 struct input_handle *handle = to_handle_h(node);
1002 input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); 1001 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1003 input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); 1002 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
1004 input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04)); 1003 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
1005 input_sync(handle->dev); 1004 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1006 } 1005 }
1007 } 1006 }
1008 1007
@@ -1011,23 +1010,6 @@ static void kbd_bh(unsigned long dummy)
1011 1010
1012DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); 1011DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
1013 1012
1014/*
1015 * This allows a newly plugged keyboard to pick the LED state.
1016 */
1017static void kbd_refresh_leds(struct input_handle *handle)
1018{
1019 unsigned char leds = ledstate;
1020
1021 tasklet_disable(&keyboard_tasklet);
1022 if (leds != 0xff) {
1023 input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1024 input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02));
1025 input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04));
1026 input_sync(handle->dev);
1027 }
1028 tasklet_enable(&keyboard_tasklet);
1029}
1030
1031#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ 1013#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
1032 defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\ 1014 defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
1033 defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ 1015 defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
@@ -1043,7 +1025,7 @@ static const unsigned short x86_keycodes[256] =
1043 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,
1044 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,
1045 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,
1046 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,
1047 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,
1048 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,
1049 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,
@@ -1065,38 +1047,55 @@ extern void sun_do_break(void);
1065static int emulate_raw(struct vc_data *vc, unsigned int keycode, 1047static int emulate_raw(struct vc_data *vc, unsigned int keycode,
1066 unsigned char up_flag) 1048 unsigned char up_flag)
1067{ 1049{
1068 if (keycode > 255 || !x86_keycodes[keycode]) 1050 int code;
1069 return -1;
1070 1051
1071 switch (keycode) { 1052 switch (keycode) {
1072 case KEY_PAUSE: 1053 case KEY_PAUSE:
1073 put_queue(vc, 0xe1); 1054 put_queue(vc, 0xe1);
1074 put_queue(vc, 0x1d | up_flag); 1055 put_queue(vc, 0x1d | up_flag);
1075 put_queue(vc, 0x45 | up_flag); 1056 put_queue(vc, 0x45 | up_flag);
1076 return 0; 1057 break;
1058
1077 case KEY_HANGEUL: 1059 case KEY_HANGEUL:
1078 if (!up_flag) 1060 if (!up_flag)
1079 put_queue(vc, 0xf2); 1061 put_queue(vc, 0xf2);
1080 return 0; 1062 break;
1063
1081 case KEY_HANJA: 1064 case KEY_HANJA:
1082 if (!up_flag) 1065 if (!up_flag)
1083 put_queue(vc, 0xf1); 1066 put_queue(vc, 0xf1);
1084 return 0; 1067 break;
1085 }
1086 1068
1087 if (keycode == KEY_SYSRQ && sysrq_alt) { 1069 case KEY_SYSRQ:
1088 put_queue(vc, 0x54 | up_flag); 1070 /*
1089 return 0; 1071 * Real AT keyboards (that's what we're trying
1090 } 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;
1091 1089
1092 if (x86_keycodes[keycode] & 0x100) 1090 code = x86_keycodes[keycode];
1093 put_queue(vc, 0xe0); 1091 if (!code)
1092 return -1;
1094 1093
1095 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);
1096 1097
1097 if (keycode == KEY_SYSRQ) { 1098 break;
1098 put_queue(vc, 0xe0);
1099 put_queue(vc, 0x37 | up_flag);
1100 } 1099 }
1101 1100
1102 return 0; 1101 return 0;
@@ -1298,16 +1297,15 @@ static struct input_handle *kbd_connect(struct input_handler *handler,
1298 if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) 1297 if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
1299 return NULL; 1298 return NULL;
1300 1299
1301 if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL))) 1300 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
1301 if (!handle)
1302 return NULL; 1302 return NULL;
1303 memset(handle, 0, sizeof(struct input_handle));
1304 1303
1305 handle->dev = dev; 1304 handle->dev = dev;
1306 handle->handler = handler; 1305 handle->handler = handler;
1307 handle->name = "kbd"; 1306 handle->name = "kbd";
1308 1307
1309 input_open_device(handle); 1308 input_open_device(handle);
1310 kbd_refresh_leds(handle);
1311 1309
1312 return handle; 1310 return handle;
1313} 1311}
@@ -1318,6 +1316,24 @@ static void kbd_disconnect(struct input_handle *handle)
1318 kfree(handle); 1316 kfree(handle);
1319} 1317}
1320 1318
1319/*
1320 * Start keyboard handler on the new keyboard by refreshing LED state to
1321 * match the rest of the system.
1322 */
1323static void kbd_start(struct input_handle *handle)
1324{
1325 unsigned char leds = ledstate;
1326
1327 tasklet_disable(&keyboard_tasklet);
1328 if (leds != 0xff) {
1329 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1330 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
1331 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
1332 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1333 }
1334 tasklet_enable(&keyboard_tasklet);
1335}
1336
1321static struct input_device_id kbd_ids[] = { 1337static struct input_device_id kbd_ids[] = {
1322 { 1338 {
1323 .flags = INPUT_DEVICE_ID_MATCH_EVBIT, 1339 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
@@ -1338,6 +1354,7 @@ static struct input_handler kbd_handler = {
1338 .event = kbd_event, 1354 .event = kbd_event,
1339 .connect = kbd_connect, 1355 .connect = kbd_connect,
1340 .disconnect = kbd_disconnect, 1356 .disconnect = kbd_disconnect,
1357 .start = kbd_start,
1341 .name = "kbd", 1358 .name = "kbd",
1342 .id_table = kbd_ids, 1359 .id_table = kbd_ids,
1343}; 1360};
@@ -1346,15 +1363,15 @@ int __init kbd_init(void)
1346{ 1363{
1347 int i; 1364 int i;
1348 1365
1349 kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS; 1366 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1350 kbd0.ledmode = LED_SHOW_FLAGS; 1367 kbd_table[i].ledflagstate = KBD_DEFLEDS;
1351 kbd0.lockstate = KBD_DEFLOCK; 1368 kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
1352 kbd0.slockstate = 0; 1369 kbd_table[i].ledmode = LED_SHOW_FLAGS;
1353 kbd0.modeflags = KBD_DEFMODE; 1370 kbd_table[i].lockstate = KBD_DEFLOCK;
1354 kbd0.kbdmode = VC_XLATE; 1371 kbd_table[i].slockstate = 0;
1355 1372 kbd_table[i].modeflags = KBD_DEFMODE;
1356 for (i = 0 ; i < MAX_NR_CONSOLES ; i++) 1373 kbd_table[i].kbdmode = VC_XLATE;
1357 kbd_table[i] = kbd0; 1374 }
1358 1375
1359 input_register_handler(&kbd_handler); 1376 input_register_handler(&kbd_handler);
1360 1377