aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/input.c279
1 files changed, 168 insertions, 111 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 8dcd3931fa62..db52ba0a316f 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -18,6 +18,7 @@
18#include <linux/random.h> 18#include <linux/random.h>
19#include <linux/major.h> 19#include <linux/major.h>
20#include <linux/proc_fs.h> 20#include <linux/proc_fs.h>
21#include <linux/seq_file.h>
21#include <linux/interrupt.h> 22#include <linux/interrupt.h>
22#include <linux/poll.h> 23#include <linux/poll.h>
23#include <linux/device.h> 24#include <linux/device.h>
@@ -316,26 +317,6 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st
316 return NULL; 317 return NULL;
317} 318}
318 319
319static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
320 int max, int add_cr)
321{
322 int i;
323 int len = 0;
324
325 for (i = NBITS(max) - 1; i > 0; i--)
326 if (bitmap[i])
327 break;
328
329 for (; i >= 0; i--)
330 len += snprintf(buf + len, max(buf_size - len, 0),
331 "%lx%s", bitmap[i], i > 0 ? " " : "");
332
333 if (add_cr)
334 len += snprintf(buf + len, max(buf_size - len, 0), "\n");
335
336 return len;
337}
338
339#ifdef CONFIG_PROC_FS 320#ifdef CONFIG_PROC_FS
340 321
341static struct proc_dir_entry *proc_bus_input_dir; 322static struct proc_dir_entry *proc_bus_input_dir;
@@ -348,7 +329,7 @@ static inline void input_wakeup_procfs_readers(void)
348 wake_up(&input_devices_poll_wait); 329 wake_up(&input_devices_poll_wait);
349} 330}
350 331
351static unsigned int input_devices_poll(struct file *file, poll_table *wait) 332static unsigned int input_proc_devices_poll(struct file *file, poll_table *wait)
352{ 333{
353 int state = input_devices_state; 334 int state = input_devices_state;
354 poll_wait(file, &input_devices_poll_wait, wait); 335 poll_wait(file, &input_devices_poll_wait, wait);
@@ -357,114 +338,171 @@ static unsigned int input_devices_poll(struct file *file, poll_table *wait)
357 return 0; 338 return 0;
358} 339}
359 340
360#define SPRINTF_BIT(ev, bm) \ 341static struct list_head *list_get_nth_element(struct list_head *list, loff_t *pos)
361 do { \ 342{
362 len += sprintf(buf + len, "B: %s=", #ev); \ 343 struct list_head *node;
363 len += input_print_bitmap(buf + len, INT_MAX, \ 344 loff_t i = 0;
364 dev->bm##bit, ev##_MAX, 1); \
365 } while (0)
366 345
367#define TEST_AND_SPRINTF_BIT(ev, bm) \ 346 list_for_each(node, list)
368 do { \ 347 if (i++ == *pos)
369 if (test_bit(EV_##ev, dev->evbit)) \ 348 return node;
370 SPRINTF_BIT(ev, bm); \ 349
371 } while (0) 350 return NULL;
351}
372 352
373static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) 353static struct list_head *list_get_next_element(struct list_head *list, struct list_head *element, loff_t *pos)
374{ 354{
375 struct input_dev *dev; 355 if (element->next == list)
376 struct input_handle *handle; 356 return NULL;
377 const char *path;
378 357
379 off_t at = 0; 358 ++(*pos);
380 int len, cnt = 0; 359 return element->next;
360}
381 361
382 list_for_each_entry(dev, &input_dev_list, node) { 362static void *input_devices_seq_start(struct seq_file *seq, loff_t *pos)
363{
364 /* acquire lock here ... Yes, we do need locking, I knowi, I know... */
383 365
384 path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); 366 return list_get_nth_element(&input_dev_list, pos);
367}
385 368
386 len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n", 369static void *input_devices_seq_next(struct seq_file *seq, void *v, loff_t *pos)
387 dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version); 370{
371 return list_get_next_element(&input_dev_list, v, pos);
372}
388 373
389 len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); 374static void input_devices_seq_stop(struct seq_file *seq, void *v)
390 len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : ""); 375{
391 len += sprintf(buf + len, "S: Sysfs=%s\n", path ? path : ""); 376 /* release lock here */
392 len += sprintf(buf + len, "H: Handlers="); 377}
393 378
394 list_for_each_entry(handle, &dev->h_list, d_node) 379static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
395 len += sprintf(buf + len, "%s ", handle->name); 380 unsigned long *bitmap, int max)
396 381{
397 len += sprintf(buf + len, "\n"); 382 int i;
398
399 SPRINTF_BIT(EV, ev);
400 TEST_AND_SPRINTF_BIT(KEY, key);
401 TEST_AND_SPRINTF_BIT(REL, rel);
402 TEST_AND_SPRINTF_BIT(ABS, abs);
403 TEST_AND_SPRINTF_BIT(MSC, msc);
404 TEST_AND_SPRINTF_BIT(LED, led);
405 TEST_AND_SPRINTF_BIT(SND, snd);
406 TEST_AND_SPRINTF_BIT(FF, ff);
407 TEST_AND_SPRINTF_BIT(SW, sw);
408
409 len += sprintf(buf + len, "\n");
410
411 at += len;
412
413 if (at >= pos) {
414 if (!*start) {
415 *start = buf + (pos - (at - len));
416 cnt = at - pos;
417 } else cnt += len;
418 buf += len;
419 if (cnt >= count)
420 break;
421 }
422 383
423 kfree(path); 384 for (i = NBITS(max) - 1; i > 0; i--)
424 } 385 if (bitmap[i])
386 break;
387
388 seq_printf(seq, "B: %s=", name);
389 for (; i >= 0; i--)
390 seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : "");
391 seq_putc(seq, '\n');
392}
393
394static int input_devices_seq_show(struct seq_file *seq, void *v)
395{
396 struct input_dev *dev = container_of(v, struct input_dev, node);
397 const char *path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL);
398 struct input_handle *handle;
399
400 seq_printf(seq, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
401 dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version);
402
403 seq_printf(seq, "N: Name=\"%s\"\n", dev->name ? dev->name : "");
404 seq_printf(seq, "P: Phys=%s\n", dev->phys ? dev->phys : "");
405 seq_printf(seq, "S: Sysfs=%s\n", path ? path : "");
406 seq_printf(seq, "H: Handlers=");
425 407
426 if (&dev->node == &input_dev_list) 408 list_for_each_entry(handle, &dev->h_list, d_node)
427 *eof = 1; 409 seq_printf(seq, "%s ", handle->name);
410 seq_putc(seq, '\n');
428 411
429 return (count > cnt) ? cnt : count; 412 input_seq_print_bitmap(seq, "EV", dev->evbit, EV_MAX);
413 if (test_bit(EV_KEY, dev->evbit))
414 input_seq_print_bitmap(seq, "KEY", dev->keybit, KEY_MAX);
415 if (test_bit(EV_REL, dev->evbit))
416 input_seq_print_bitmap(seq, "REL", dev->relbit, REL_MAX);
417 if (test_bit(EV_ABS, dev->evbit))
418 input_seq_print_bitmap(seq, "ABS", dev->absbit, ABS_MAX);
419 if (test_bit(EV_MSC, dev->evbit))
420 input_seq_print_bitmap(seq, "MSC", dev->mscbit, MSC_MAX);
421 if (test_bit(EV_LED, dev->evbit))
422 input_seq_print_bitmap(seq, "LED", dev->ledbit, LED_MAX);
423 if (test_bit(EV_SND, dev->evbit))
424 input_seq_print_bitmap(seq, "SND", dev->sndbit, SND_MAX);
425 if (test_bit(EV_FF, dev->evbit))
426 input_seq_print_bitmap(seq, "FF", dev->ffbit, FF_MAX);
427 if (test_bit(EV_SW, dev->evbit))
428 input_seq_print_bitmap(seq, "SW", dev->swbit, SW_MAX);
429
430 seq_putc(seq, '\n');
431
432 kfree(path);
433 return 0;
430} 434}
431 435
432static int input_handlers_read(char *buf, char **start, off_t pos, int count, int *eof, void *data) 436static struct seq_operations input_devices_seq_ops = {
437 .start = input_devices_seq_start,
438 .next = input_devices_seq_next,
439 .stop = input_devices_seq_stop,
440 .show = input_devices_seq_show,
441};
442
443static int input_proc_devices_open(struct inode *inode, struct file *file)
433{ 444{
434 struct input_handler *handler; 445 return seq_open(file, &input_devices_seq_ops);
446}
435 447
436 off_t at = 0; 448static struct file_operations input_devices_fileops = {
437 int len = 0, cnt = 0; 449 .owner = THIS_MODULE,
438 int i = 0; 450 .open = input_proc_devices_open,
451 .poll = input_proc_devices_poll,
452 .read = seq_read,
453 .llseek = seq_lseek,
454 .release = seq_release,
455};
439 456
440 list_for_each_entry(handler, &input_handler_list, node) { 457static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos)
458{
459 /* acquire lock here ... Yes, we do need locking, I knowi, I know... */
460 seq->private = (void *)(unsigned long)*pos;
461 return list_get_nth_element(&input_handler_list, pos);
462}
441 463
442 if (handler->fops) 464static void *input_handlers_seq_next(struct seq_file *seq, void *v, loff_t *pos)
443 len = sprintf(buf, "N: Number=%d Name=%s Minor=%d\n", 465{
444 i++, handler->name, handler->minor); 466 seq->private = (void *)(unsigned long)(*pos + 1);
445 else 467 return list_get_next_element(&input_handler_list, v, pos);
446 len = sprintf(buf, "N: Number=%d Name=%s\n", 468}
447 i++, handler->name);
448 469
449 at += len; 470static void input_handlers_seq_stop(struct seq_file *seq, void *v)
471{
472 /* release lock here */
473}
450 474
451 if (at >= pos) { 475static int input_handlers_seq_show(struct seq_file *seq, void *v)
452 if (!*start) { 476{
453 *start = buf + (pos - (at - len)); 477 struct input_handler *handler = container_of(v, struct input_handler, node);
454 cnt = at - pos;
455 } else cnt += len;
456 buf += len;
457 if (cnt >= count)
458 break;
459 }
460 }
461 if (&handler->node == &input_handler_list)
462 *eof = 1;
463 478
464 return (count > cnt) ? cnt : count; 479 seq_printf(seq, "N: Number=%ld Name=%s",
480 (unsigned long)seq->private, handler->name);
481 if (handler->fops)
482 seq_printf(seq, " Minor=%d", handler->minor);
483 seq_putc(seq, '\n');
484
485 return 0;
465} 486}
487static struct seq_operations input_handlers_seq_ops = {
488 .start = input_handlers_seq_start,
489 .next = input_handlers_seq_next,
490 .stop = input_handlers_seq_stop,
491 .show = input_handlers_seq_show,
492};
466 493
467static struct file_operations input_fileops; 494static int input_proc_handlers_open(struct inode *inode, struct file *file)
495{
496 return seq_open(file, &input_handlers_seq_ops);
497}
498
499static struct file_operations input_handlers_fileops = {
500 .owner = THIS_MODULE,
501 .open = input_proc_handlers_open,
502 .read = seq_read,
503 .llseek = seq_lseek,
504 .release = seq_release,
505};
468 506
469static int __init input_proc_init(void) 507static int __init input_proc_init(void)
470{ 508{
@@ -476,20 +514,19 @@ static int __init input_proc_init(void)
476 514
477 proc_bus_input_dir->owner = THIS_MODULE; 515 proc_bus_input_dir->owner = THIS_MODULE;
478 516
479 entry = create_proc_read_entry("devices", 0, proc_bus_input_dir, input_devices_read, NULL); 517 entry = create_proc_entry("devices", 0, proc_bus_input_dir);
480 if (!entry) 518 if (!entry)
481 goto fail1; 519 goto fail1;
482 520
483 entry->owner = THIS_MODULE; 521 entry->owner = THIS_MODULE;
484 input_fileops = *entry->proc_fops; 522 entry->proc_fops = &input_devices_fileops;
485 input_fileops.poll = input_devices_poll;
486 entry->proc_fops = &input_fileops;
487 523
488 entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL); 524 entry = create_proc_entry("handlers", 0, proc_bus_input_dir);
489 if (!entry) 525 if (!entry)
490 goto fail2; 526 goto fail2;
491 527
492 entry->owner = THIS_MODULE; 528 entry->owner = THIS_MODULE;
529 entry->proc_fops = &input_handlers_fileops;
493 530
494 return 0; 531 return 0;
495 532
@@ -631,6 +668,26 @@ static struct attribute_group input_dev_id_attr_group = {
631 .attrs = input_dev_id_attrs, 668 .attrs = input_dev_id_attrs,
632}; 669};
633 670
671static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
672 int max, int add_cr)
673{
674 int i;
675 int len = 0;
676
677 for (i = NBITS(max) - 1; i > 0; i--)
678 if (bitmap[i])
679 break;
680
681 for (; i >= 0; i--)
682 len += snprintf(buf + len, max(buf_size - len, 0),
683 "%lx%s", bitmap[i], i > 0 ? " " : "");
684
685 if (add_cr)
686 len += snprintf(buf + len, max(buf_size - len, 0), "\n");
687
688 return len;
689}
690
634#define INPUT_DEV_CAP_ATTR(ev, bm) \ 691#define INPUT_DEV_CAP_ATTR(ev, bm) \
635static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \ 692static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \
636{ \ 693{ \