aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/keyboard.c71
-rw-r--r--drivers/input/evdev.c29
-rw-r--r--drivers/input/input.c87
3 files changed, 119 insertions, 68 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index cb8d691576da..3d211e8553f7 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -159,65 +159,41 @@ static int sysrq_alt_use;
159static int sysrq_alt; 159static int sysrq_alt;
160 160
161/* 161/*
162 * Translation of scancodes to keycodes. We set them on only the first attached 162 * Translation of scancodes to keycodes. We set them on only the first
163 * keyboard - for per-keyboard setting, /dev/input/event is more useful. 163 * keyboard in the list that accepts the scancode and keycode.
164 * Explanation for not choosing the first attached keyboard anymore:
165 * USB keyboards for example have two event devices: one for all "normal"
166 * keys and one for extra function keys (like "volume up", "make coffee",
167 * etc.). So this means that scancodes for the extra function keys won't
168 * be valid for the first event device, but will be for the second.
164 */ 169 */
165int getkeycode(unsigned int scancode) 170int getkeycode(unsigned int scancode)
166{ 171{
167 struct list_head *node; 172 struct input_handle *handle;
168 struct input_dev *dev = NULL; 173 int keycode;
174 int error = -ENODEV;
169 175
170 list_for_each(node, &kbd_handler.h_list) { 176 list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
171 struct input_handle *handle = to_handle_h(node); 177 error = handle->dev->getkeycode(handle->dev, scancode, &keycode);
172 if (handle->dev->keycodesize) { 178 if (!error)
173 dev = handle->dev; 179 return keycode;
174 break;
175 }
176 } 180 }
177 181
178 if (!dev) 182 return error;
179 return -ENODEV;
180
181 if (scancode >= dev->keycodemax)
182 return -EINVAL;
183
184 return INPUT_KEYCODE(dev, scancode);
185} 183}
186 184
187int setkeycode(unsigned int scancode, unsigned int keycode) 185int setkeycode(unsigned int scancode, unsigned int keycode)
188{ 186{
189 struct list_head *node; 187 struct input_handle *handle;
190 struct input_dev *dev = NULL; 188 int error = -ENODEV;
191 unsigned int i, oldkey;
192 189
193 list_for_each(node, &kbd_handler.h_list) { 190 list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
194 struct input_handle *handle = to_handle_h(node); 191 error = handle->dev->setkeycode(handle->dev, scancode, keycode);
195 if (handle->dev->keycodesize) { 192 if (!error)
196 dev = handle->dev;
197 break; 193 break;
198 }
199 } 194 }
200 195
201 if (!dev) 196 return error;
202 return -ENODEV;
203
204 if (scancode >= dev->keycodemax)
205 return -EINVAL;
206 if (keycode < 0 || keycode > KEY_MAX)
207 return -EINVAL;
208 if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
209 return -EINVAL;
210
211 oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode);
212
213 clear_bit(oldkey, dev->keybit);
214 set_bit(keycode, dev->keybit);
215
216 for (i = 0; i < dev->keycodemax; i++)
217 if (INPUT_KEYCODE(dev,i) == oldkey)
218 set_bit(oldkey, dev->keybit);
219
220 return 0;
221} 197}
222 198
223/* 199/*
@@ -225,10 +201,9 @@ int setkeycode(unsigned int scancode, unsigned int keycode)
225 */ 201 */
226static void kd_nosound(unsigned long ignored) 202static void kd_nosound(unsigned long ignored)
227{ 203{
228 struct list_head *node; 204 struct input_handle *handle;
229 205
230 list_for_each(node, &kbd_handler.h_list) { 206 list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
231 struct input_handle *handle = to_handle_h(node);
232 if (test_bit(EV_SND, handle->dev->evbit)) { 207 if (test_bit(EV_SND, handle->dev->evbit)) {
233 if (test_bit(SND_TONE, handle->dev->sndbit)) 208 if (test_bit(SND_TONE, handle->dev->sndbit))
234 input_inject_event(handle, EV_SND, SND_TONE, 0); 209 input_inject_event(handle, EV_SND, SND_TONE, 0);
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 6439f378f6cc..64b47de052bb 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -434,32 +434,21 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
434 case EVIOCGKEYCODE: 434 case EVIOCGKEYCODE:
435 if (get_user(t, ip)) 435 if (get_user(t, ip))
436 return -EFAULT; 436 return -EFAULT;
437 if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) 437
438 return -EINVAL; 438 error = dev->getkeycode(dev, t, &v);
439 if (put_user(INPUT_KEYCODE(dev, t), ip + 1)) 439 if (error)
440 return error;
441
442 if (put_user(v, ip + 1))
440 return -EFAULT; 443 return -EFAULT;
444
441 return 0; 445 return 0;
442 446
443 case EVIOCSKEYCODE: 447 case EVIOCSKEYCODE:
444 if (get_user(t, ip)) 448 if (get_user(t, ip) || get_user(v, ip + 1))
445 return -EFAULT;
446 if (t < 0 || t >= dev->keycodemax || !dev->keycodesize)
447 return -EINVAL;
448 if (get_user(v, ip + 1))
449 return -EFAULT; 449 return -EFAULT;
450 if (v < 0 || v > KEY_MAX)
451 return -EINVAL;
452 if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8)))
453 return -EINVAL;
454
455 u = SET_INPUT_KEYCODE(dev, t, v);
456 clear_bit(u, dev->keybit);
457 set_bit(v, dev->keybit);
458 for (i = 0; i < dev->keycodemax; i++)
459 if (INPUT_KEYCODE(dev, i) == u)
460 set_bit(u, dev->keybit);
461 450
462 return 0; 451 return dev->setkeycode(dev, t, v);
463 452
464 case EVIOCSFF: 453 case EVIOCSFF:
465 if (copy_from_user(&effect, p, sizeof(effect))) 454 if (copy_from_user(&effect, p, sizeof(effect)))
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 4486402fbf5d..26393a606e6f 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -299,6 +299,87 @@ void input_close_device(struct input_handle *handle)
299} 299}
300EXPORT_SYMBOL(input_close_device); 300EXPORT_SYMBOL(input_close_device);
301 301
302static int input_fetch_keycode(struct input_dev *dev, int scancode)
303{
304 switch (dev->keycodesize) {
305 case 1:
306 return ((u8 *)dev->keycode)[scancode];
307
308 case 2:
309 return ((u16 *)dev->keycode)[scancode];
310
311 default:
312 return ((u32 *)dev->keycode)[scancode];
313 }
314}
315
316static int input_default_getkeycode(struct input_dev *dev,
317 int scancode, int *keycode)
318{
319 if (!dev->keycodesize)
320 return -EINVAL;
321
322 if (scancode < 0 || scancode >= dev->keycodemax)
323 return -EINVAL;
324
325 *keycode = input_fetch_keycode(dev, scancode);
326
327 return 0;
328}
329
330static int input_default_setkeycode(struct input_dev *dev,
331 int scancode, int keycode)
332{
333 int old_keycode;
334 int i;
335
336 if (scancode < 0 || scancode >= dev->keycodemax)
337 return -EINVAL;
338
339 if (keycode < 0 || keycode > KEY_MAX)
340 return -EINVAL;
341
342 if (!dev->keycodesize)
343 return -EINVAL;
344
345 if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
346 return -EINVAL;
347
348 switch (dev->keycodesize) {
349 case 1: {
350 u8 *k = (u8 *)dev->keycode;
351 old_keycode = k[scancode];
352 k[scancode] = keycode;
353 break;
354 }
355 case 2: {
356 u16 *k = (u16 *)dev->keycode;
357 old_keycode = k[scancode];
358 k[scancode] = keycode;
359 break;
360 }
361 default: {
362 u32 *k = (u32 *)dev->keycode;
363 old_keycode = k[scancode];
364 k[scancode] = keycode;
365 break;
366 }
367 }
368
369 clear_bit(old_keycode, dev->keybit);
370 set_bit(keycode, dev->keybit);
371
372 for (i = 0; i < dev->keycodemax; i++) {
373 if (input_fetch_keycode(dev, i) == old_keycode) {
374 set_bit(old_keycode, dev->keybit);
375 break; /* Setting the bit twice is useless, so break */
376 }
377 }
378
379 return 0;
380}
381
382
302static void input_link_handle(struct input_handle *handle) 383static void input_link_handle(struct input_handle *handle)
303{ 384{
304 list_add_tail(&handle->d_node, &handle->dev->h_list); 385 list_add_tail(&handle->d_node, &handle->dev->h_list);
@@ -978,6 +1059,12 @@ int input_register_device(struct input_dev *dev)
978 dev->rep[REP_PERIOD] = 33; 1059 dev->rep[REP_PERIOD] = 33;
979 } 1060 }
980 1061
1062 if (!dev->getkeycode)
1063 dev->getkeycode = input_default_getkeycode;
1064
1065 if (!dev->setkeycode)
1066 dev->setkeycode = input_default_setkeycode;
1067
981 list_add_tail(&dev->node, &input_dev_list); 1068 list_add_tail(&dev->node, &input_dev_list);
982 1069
983 snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), 1070 snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),