aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/keyboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/keyboard.c')
-rw-r--r--drivers/char/keyboard.c219
1 files changed, 119 insertions, 100 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 737be953cc58..f706b1dffdb3 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -46,8 +46,6 @@
46 46
47extern void ctrl_alt_del(void); 47extern void ctrl_alt_del(void);
48 48
49#define to_handle_h(n) container_of(n, struct input_handle, h_node)
50
51/* 49/*
52 * Exported functions/variables 50 * Exported functions/variables
53 */ 51 */
@@ -132,6 +130,7 @@ int shift_state = 0;
132 */ 130 */
133 131
134static struct input_handler kbd_handler; 132static struct input_handler kbd_handler;
133static DEFINE_SPINLOCK(kbd_event_lock);
135static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ 134static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
136static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ 135static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
137static int dead_key_next; 136static int dead_key_next;
@@ -190,78 +189,89 @@ EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
190 * etc.). So this means that scancodes for the extra function keys won't 189 * etc.). So this means that scancodes for the extra function keys won't
191 * be valid for the first event device, but will be for the second. 190 * be valid for the first event device, but will be for the second.
192 */ 191 */
192
193struct getset_keycode_data {
194 unsigned int scancode;
195 unsigned int keycode;
196 int error;
197};
198
199static int getkeycode_helper(struct input_handle *handle, void *data)
200{
201 struct getset_keycode_data *d = data;
202
203 d->error = input_get_keycode(handle->dev, d->scancode, &d->keycode);
204
205 return d->error == 0; /* stop as soon as we successfully get one */
206}
207
193int getkeycode(unsigned int scancode) 208int getkeycode(unsigned int scancode)
194{ 209{
195 struct input_handle *handle; 210 struct getset_keycode_data d = { scancode, 0, -ENODEV };
196 int keycode;
197 int error = -ENODEV;
198 211
199 list_for_each_entry(handle, &kbd_handler.h_list, h_node) { 212 input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper);
200 error = input_get_keycode(handle->dev, scancode, &keycode);
201 if (!error)
202 return keycode;
203 }
204 213
205 return error; 214 return d.error ?: d.keycode;
215}
216
217static int setkeycode_helper(struct input_handle *handle, void *data)
218{
219 struct getset_keycode_data *d = data;
220
221 d->error = input_set_keycode(handle->dev, d->scancode, d->keycode);
222
223 return d->error == 0; /* stop as soon as we successfully set one */
206} 224}
207 225
208int setkeycode(unsigned int scancode, unsigned int keycode) 226int setkeycode(unsigned int scancode, unsigned int keycode)
209{ 227{
210 struct input_handle *handle; 228 struct getset_keycode_data d = { scancode, keycode, -ENODEV };
211 int error = -ENODEV;
212 229
213 list_for_each_entry(handle, &kbd_handler.h_list, h_node) { 230 input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper);
214 error = input_set_keycode(handle->dev, scancode, keycode);
215 if (!error)
216 break;
217 }
218 231
219 return error; 232 return d.error;
220} 233}
221 234
222/* 235/*
223 * Making beeps and bells. 236 * Making beeps and bells. Note that we prefer beeps to bells, but when
237 * shutting the sound off we do both.
224 */ 238 */
225static void kd_nosound(unsigned long ignored) 239
240static int kd_sound_helper(struct input_handle *handle, void *data)
226{ 241{
227 struct input_handle *handle; 242 unsigned int *hz = data;
243 struct input_dev *dev = handle->dev;
228 244
229 list_for_each_entry(handle, &kbd_handler.h_list, h_node) { 245 if (test_bit(EV_SND, dev->evbit)) {
230 if (test_bit(EV_SND, handle->dev->evbit)) { 246 if (test_bit(SND_TONE, dev->sndbit)) {
231 if (test_bit(SND_TONE, handle->dev->sndbit)) 247 input_inject_event(handle, EV_SND, SND_TONE, *hz);
232 input_inject_event(handle, EV_SND, SND_TONE, 0); 248 if (*hz)
233 if (test_bit(SND_BELL, handle->dev->sndbit)) 249 return 0;
234 input_inject_event(handle, EV_SND, SND_BELL, 0);
235 } 250 }
251 if (test_bit(SND_BELL, dev->sndbit))
252 input_inject_event(handle, EV_SND, SND_BELL, *hz ? 1 : 0);
236 } 253 }
254
255 return 0;
256}
257
258static void kd_nosound(unsigned long ignored)
259{
260 static unsigned int zero;
261
262 input_handler_for_each_handle(&kbd_handler, &zero, kd_sound_helper);
237} 263}
238 264
239static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0); 265static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
240 266
241void kd_mksound(unsigned int hz, unsigned int ticks) 267void kd_mksound(unsigned int hz, unsigned int ticks)
242{ 268{
243 struct list_head *node; 269 del_timer_sync(&kd_mksound_timer);
244 270
245 del_timer(&kd_mksound_timer); 271 input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper);
246 272
247 if (hz) { 273 if (hz && ticks)
248 list_for_each_prev(node, &kbd_handler.h_list) { 274 mod_timer(&kd_mksound_timer, jiffies + ticks);
249 struct input_handle *handle = to_handle_h(node);
250 if (test_bit(EV_SND, handle->dev->evbit)) {
251 if (test_bit(SND_TONE, handle->dev->sndbit)) {
252 input_inject_event(handle, EV_SND, SND_TONE, hz);
253 break;
254 }
255 if (test_bit(SND_BELL, handle->dev->sndbit)) {
256 input_inject_event(handle, EV_SND, SND_BELL, 1);
257 break;
258 }
259 }
260 }
261 if (ticks)
262 mod_timer(&kd_mksound_timer, jiffies + ticks);
263 } else
264 kd_nosound(0);
265} 275}
266EXPORT_SYMBOL(kd_mksound); 276EXPORT_SYMBOL(kd_mksound);
267 277
@@ -269,27 +279,34 @@ EXPORT_SYMBOL(kd_mksound);
269 * Setting the keyboard rate. 279 * Setting the keyboard rate.
270 */ 280 */
271 281
272int kbd_rate(struct kbd_repeat *rep) 282static int kbd_rate_helper(struct input_handle *handle, void *data)
273{ 283{
274 struct list_head *node; 284 struct input_dev *dev = handle->dev;
275 unsigned int d = 0; 285 struct kbd_repeat *rep = data;
276 unsigned int p = 0; 286
277 287 if (test_bit(EV_REP, dev->evbit)) {
278 list_for_each(node, &kbd_handler.h_list) { 288
279 struct input_handle *handle = to_handle_h(node); 289 if (rep[0].delay > 0)
280 struct input_dev *dev = handle->dev; 290 input_inject_event(handle,
281 291 EV_REP, REP_DELAY, rep[0].delay);
282 if (test_bit(EV_REP, dev->evbit)) { 292 if (rep[0].period > 0)
283 if (rep->delay > 0) 293 input_inject_event(handle,
284 input_inject_event(handle, EV_REP, REP_DELAY, rep->delay); 294 EV_REP, REP_PERIOD, rep[0].period);
285 if (rep->period > 0) 295
286 input_inject_event(handle, EV_REP, REP_PERIOD, rep->period); 296 rep[1].delay = dev->rep[REP_DELAY];
287 d = dev->rep[REP_DELAY]; 297 rep[1].period = dev->rep[REP_PERIOD];
288 p = dev->rep[REP_PERIOD];
289 }
290 } 298 }
291 rep->delay = d; 299
292 rep->period = p; 300 return 0;
301}
302
303int kbd_rate(struct kbd_repeat *rep)
304{
305 struct kbd_repeat data[2] = { *rep };
306
307 input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper);
308 *rep = data[1]; /* Copy currently used settings */
309
293 return 0; 310 return 0;
294} 311}
295 312
@@ -997,36 +1014,36 @@ static inline unsigned char getleds(void)
997 return leds; 1014 return leds;
998} 1015}
999 1016
1017static int kbd_update_leds_helper(struct input_handle *handle, void *data)
1018{
1019 unsigned char leds = *(unsigned char *)data;
1020
1021 if (test_bit(EV_LED, handle->dev->evbit)) {
1022 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1023 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
1024 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
1025 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1026 }
1027
1028 return 0;
1029}
1030
1000/* 1031/*
1001 * This routine is the bottom half of the keyboard interrupt 1032 * This is the tasklet that updates LED state on all keyboards
1002 * routine, and runs with all interrupts enabled. It does 1033 * attached to the box. The reason we use tasklet is that we
1003 * console changing, led setting and copy_to_cooked, which can 1034 * need to handle the scenario when keyboard handler is not
1004 * take a reasonably long time. 1035 * registered yet but we already getting updates form VT to
1005 * 1036 * update led state.
1006 * Aside from timing (which isn't really that important for
1007 * keyboard interrupts as they happen often), using the software
1008 * interrupt routines for this thing allows us to easily mask
1009 * this when we don't want any of the above to happen.
1010 * This allows for easy and efficient race-condition prevention
1011 * for kbd_start => input_inject_event(dev, EV_LED, ...) => ...
1012 */ 1037 */
1013
1014static void kbd_bh(unsigned long dummy) 1038static void kbd_bh(unsigned long dummy)
1015{ 1039{
1016 struct list_head *node;
1017 unsigned char leds = getleds(); 1040 unsigned char leds = getleds();
1018 1041
1019 if (leds != ledstate) { 1042 if (leds != ledstate) {
1020 list_for_each(node, &kbd_handler.h_list) { 1043 input_handler_for_each_handle(&kbd_handler, &leds,
1021 struct input_handle *handle = to_handle_h(node); 1044 kbd_update_leds_helper);
1022 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01)); 1045 ledstate = leds;
1023 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
1024 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
1025 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1026 }
1027 } 1046 }
1028
1029 ledstate = leds;
1030} 1047}
1031 1048
1032DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); 1049DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
@@ -1136,7 +1153,7 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char u
1136static void kbd_rawcode(unsigned char data) 1153static void kbd_rawcode(unsigned char data)
1137{ 1154{
1138 struct vc_data *vc = vc_cons[fg_console].d; 1155 struct vc_data *vc = vc_cons[fg_console].d;
1139 kbd = kbd_table + fg_console; 1156 kbd = kbd_table + vc->vc_num;
1140 if (kbd->kbdmode == VC_RAW) 1157 if (kbd->kbdmode == VC_RAW)
1141 put_queue(vc, data); 1158 put_queue(vc, data);
1142} 1159}
@@ -1157,7 +1174,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
1157 tty->driver_data = vc; 1174 tty->driver_data = vc;
1158 } 1175 }
1159 1176
1160 kbd = kbd_table + fg_console; 1177 kbd = kbd_table + vc->vc_num;
1161 1178
1162 if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT) 1179 if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT)
1163 sysrq_alt = down ? keycode : 0; 1180 sysrq_alt = down ? keycode : 0;
@@ -1249,7 +1266,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
1249 1266
1250 if (keycode >= NR_KEYS) 1267 if (keycode >= NR_KEYS)
1251 if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) 1268 if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
1252 keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1); 1269 keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
1253 else 1270 else
1254 return; 1271 return;
1255 else 1272 else
@@ -1296,10 +1313,16 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
1296static void kbd_event(struct input_handle *handle, unsigned int event_type, 1313static void kbd_event(struct input_handle *handle, unsigned int event_type,
1297 unsigned int event_code, int value) 1314 unsigned int event_code, int value)
1298{ 1315{
1316 /* We are called with interrupts disabled, just take the lock */
1317 spin_lock(&kbd_event_lock);
1318
1299 if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev)) 1319 if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
1300 kbd_rawcode(value); 1320 kbd_rawcode(value);
1301 if (event_type == EV_KEY) 1321 if (event_type == EV_KEY)
1302 kbd_keycode(event_code, value, HW_RAW(handle->dev)); 1322 kbd_keycode(event_code, value, HW_RAW(handle->dev));
1323
1324 spin_unlock(&kbd_event_lock);
1325
1303 tasklet_schedule(&keyboard_tasklet); 1326 tasklet_schedule(&keyboard_tasklet);
1304 do_poke_blanked_console = 1; 1327 do_poke_blanked_console = 1;
1305 schedule_console_callback(); 1328 schedule_console_callback();
@@ -1363,15 +1386,11 @@ static void kbd_disconnect(struct input_handle *handle)
1363 */ 1386 */
1364static void kbd_start(struct input_handle *handle) 1387static void kbd_start(struct input_handle *handle)
1365{ 1388{
1366 unsigned char leds = ledstate;
1367
1368 tasklet_disable(&keyboard_tasklet); 1389 tasklet_disable(&keyboard_tasklet);
1369 if (leds != 0xff) { 1390
1370 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01)); 1391 if (ledstate != 0xff)
1371 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02)); 1392 kbd_update_leds_helper(handle, &ledstate);
1372 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04)); 1393
1373 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1374 }
1375 tasklet_enable(&keyboard_tasklet); 1394 tasklet_enable(&keyboard_tasklet);
1376} 1395}
1377 1396