diff options
| author | John W. Linville <linville@tuxdriver.com> | 2006-08-14 15:33:54 -0400 | 
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2006-08-14 15:33:54 -0400 | 
| commit | e9ffb3d7ec94083a44a8721681391beca2ffd68c (patch) | |
| tree | 6768ab487b3f44c2a4995ee61307e47760ca9b88 /drivers/input | |
| parent | 8b9411014e6f18a883c18b38f41338dbd53fddea (diff) | |
| parent | e9fa4f7bd291c29a785666e2fa5a9cf3241ee6c3 (diff) | |
Merge branch 'from-linus' into upstream
Diffstat (limited to 'drivers/input')
| -rw-r--r-- | drivers/input/evdev.c | 10 | ||||
| -rw-r--r-- | drivers/input/gameport/fm801-gp.c | 4 | ||||
| -rw-r--r-- | drivers/input/gameport/gameport.c | 66 | ||||
| -rw-r--r-- | drivers/input/input.c | 57 | ||||
| -rw-r--r-- | drivers/input/joystick/iforce/iforce-main.c | 19 | ||||
| -rw-r--r-- | drivers/input/joystick/spaceball.c | 2 | ||||
| -rw-r--r-- | drivers/input/keyboard/atkbd.c | 103 | ||||
| -rw-r--r-- | drivers/input/misc/wistron_btns.c | 20 | ||||
| -rw-r--r-- | drivers/input/mouse/logips2pp.c | 3 | ||||
| -rw-r--r-- | drivers/input/mouse/trackpoint.c | 52 | ||||
| -rw-r--r-- | drivers/input/serio/libps2.c | 5 | ||||
| -rw-r--r-- | drivers/input/serio/serio.c | 65 | 
12 files changed, 270 insertions, 136 deletions
| diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index a29d5ceb00cf..4bf48188cc91 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -127,14 +127,10 @@ static int evdev_open(struct inode * inode, struct file * file) | |||
| 127 | { | 127 | { | 
| 128 | struct evdev_list *list; | 128 | struct evdev_list *list; | 
| 129 | int i = iminor(inode) - EVDEV_MINOR_BASE; | 129 | int i = iminor(inode) - EVDEV_MINOR_BASE; | 
| 130 | int accept_err; | ||
| 131 | 130 | ||
| 132 | if (i >= EVDEV_MINORS || !evdev_table[i] || !evdev_table[i]->exist) | 131 | if (i >= EVDEV_MINORS || !evdev_table[i] || !evdev_table[i]->exist) | 
| 133 | return -ENODEV; | 132 | return -ENODEV; | 
| 134 | 133 | ||
| 135 | if ((accept_err = input_accept_process(&(evdev_table[i]->handle), file))) | ||
| 136 | return accept_err; | ||
| 137 | |||
| 138 | if (!(list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL))) | 134 | if (!(list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL))) | 
| 139 | return -ENOMEM; | 135 | return -ENOMEM; | 
| 140 | 136 | ||
| @@ -260,7 +256,7 @@ static ssize_t evdev_write(struct file * file, const char __user * buffer, size_ | |||
| 260 | 256 | ||
| 261 | if (evdev_event_from_user(buffer + retval, &event)) | 257 | if (evdev_event_from_user(buffer + retval, &event)) | 
| 262 | return -EFAULT; | 258 | return -EFAULT; | 
| 263 | input_event(list->evdev->handle.dev, event.type, event.code, event.value); | 259 | input_inject_event(&list->evdev->handle, event.type, event.code, event.value); | 
| 264 | retval += evdev_event_size(); | 260 | retval += evdev_event_size(); | 
| 265 | } | 261 | } | 
| 266 | 262 | ||
| @@ -428,8 +424,8 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, | |||
| 428 | if (get_user(v, ip + 1)) | 424 | if (get_user(v, ip + 1)) | 
| 429 | return -EFAULT; | 425 | return -EFAULT; | 
| 430 | 426 | ||
| 431 | input_event(dev, EV_REP, REP_DELAY, u); | 427 | input_inject_event(&evdev->handle, EV_REP, REP_DELAY, u); | 
| 432 | input_event(dev, EV_REP, REP_PERIOD, v); | 428 | input_inject_event(&evdev->handle, EV_REP, REP_PERIOD, v); | 
| 433 | 429 | ||
| 434 | return 0; | 430 | return 0; | 
| 435 | 431 | ||
| diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index 47e93daa0fa7..90de5afe03c2 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c | |||
| @@ -106,10 +106,10 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device | |||
| 106 | gp->gameport = port; | 106 | gp->gameport = port; | 
| 107 | gp->res_port = request_region(port->io, 0x10, "FM801 GP"); | 107 | gp->res_port = request_region(port->io, 0x10, "FM801 GP"); | 
| 108 | if (!gp->res_port) { | 108 | if (!gp->res_port) { | 
| 109 | kfree(gp); | ||
| 110 | gameport_free_port(port); | ||
| 111 | printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n", | 109 | printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n", | 
| 112 | port->io, port->io + 0x0f); | 110 | port->io, port->io + 0x0f); | 
| 111 | gameport_free_port(port); | ||
| 112 | kfree(gp); | ||
| 113 | return -EBUSY; | 113 | return -EBUSY; | 
| 114 | } | 114 | } | 
| 115 | 115 | ||
| diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 36644bff379d..3f47ae55c6f3 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
| @@ -53,6 +53,7 @@ static LIST_HEAD(gameport_list); | |||
| 53 | 53 | ||
| 54 | static struct bus_type gameport_bus; | 54 | static struct bus_type gameport_bus; | 
| 55 | 55 | ||
| 56 | static void gameport_add_driver(struct gameport_driver *drv); | ||
| 56 | static void gameport_add_port(struct gameport *gameport); | 57 | static void gameport_add_port(struct gameport *gameport); | 
| 57 | static void gameport_destroy_port(struct gameport *gameport); | 58 | static void gameport_destroy_port(struct gameport *gameport); | 
| 58 | static void gameport_reconnect_port(struct gameport *gameport); | 59 | static void gameport_reconnect_port(struct gameport *gameport); | 
| @@ -211,8 +212,14 @@ static void gameport_release_driver(struct gameport *gameport) | |||
| 211 | 212 | ||
| 212 | static void gameport_find_driver(struct gameport *gameport) | 213 | static void gameport_find_driver(struct gameport *gameport) | 
| 213 | { | 214 | { | 
| 215 | int error; | ||
| 216 | |||
| 214 | down_write(&gameport_bus.subsys.rwsem); | 217 | down_write(&gameport_bus.subsys.rwsem); | 
| 215 | device_attach(&gameport->dev); | 218 | error = device_attach(&gameport->dev); | 
| 219 | if (error < 0) | ||
| 220 | printk(KERN_WARNING | ||
| 221 | "gameport: device_attach() failed for %s (%s), error: %d\n", | ||
| 222 | gameport->phys, gameport->name, error); | ||
| 216 | up_write(&gameport_bus.subsys.rwsem); | 223 | up_write(&gameport_bus.subsys.rwsem); | 
| 217 | } | 224 | } | 
| 218 | 225 | ||
| @@ -316,7 +323,6 @@ static void gameport_remove_duplicate_events(struct gameport_event *event) | |||
| 316 | spin_unlock_irqrestore(&gameport_event_lock, flags); | 323 | spin_unlock_irqrestore(&gameport_event_lock, flags); | 
| 317 | } | 324 | } | 
| 318 | 325 | ||
| 319 | |||
| 320 | static struct gameport_event *gameport_get_event(void) | 326 | static struct gameport_event *gameport_get_event(void) | 
| 321 | { | 327 | { | 
| 322 | struct gameport_event *event; | 328 | struct gameport_event *event; | 
| @@ -342,7 +348,6 @@ static struct gameport_event *gameport_get_event(void) | |||
| 342 | static void gameport_handle_event(void) | 348 | static void gameport_handle_event(void) | 
| 343 | { | 349 | { | 
| 344 | struct gameport_event *event; | 350 | struct gameport_event *event; | 
| 345 | struct gameport_driver *gameport_drv; | ||
| 346 | 351 | ||
| 347 | mutex_lock(&gameport_mutex); | 352 | mutex_lock(&gameport_mutex); | 
| 348 | 353 | ||
| @@ -369,8 +374,7 @@ static void gameport_handle_event(void) | |||
| 369 | break; | 374 | break; | 
| 370 | 375 | ||
| 371 | case GAMEPORT_REGISTER_DRIVER: | 376 | case GAMEPORT_REGISTER_DRIVER: | 
| 372 | gameport_drv = event->object; | 377 | gameport_add_driver(event->object); | 
| 373 | driver_register(&gameport_drv->driver); | ||
| 374 | break; | 378 | break; | 
| 375 | 379 | ||
| 376 | default: | 380 | default: | 
| @@ -532,6 +536,7 @@ static void gameport_init_port(struct gameport *gameport) | |||
| 532 | if (gameport->parent) | 536 | if (gameport->parent) | 
| 533 | gameport->dev.parent = &gameport->parent->dev; | 537 | gameport->dev.parent = &gameport->parent->dev; | 
| 534 | 538 | ||
| 539 | INIT_LIST_HEAD(&gameport->node); | ||
| 535 | spin_lock_init(&gameport->timer_lock); | 540 | spin_lock_init(&gameport->timer_lock); | 
| 536 | init_timer(&gameport->poll_timer); | 541 | init_timer(&gameport->poll_timer); | 
| 537 | gameport->poll_timer.function = gameport_run_poll_handler; | 542 | gameport->poll_timer.function = gameport_run_poll_handler; | 
| @@ -544,6 +549,8 @@ static void gameport_init_port(struct gameport *gameport) | |||
| 544 | */ | 549 | */ | 
| 545 | static void gameport_add_port(struct gameport *gameport) | 550 | static void gameport_add_port(struct gameport *gameport) | 
| 546 | { | 551 | { | 
| 552 | int error; | ||
| 553 | |||
| 547 | if (gameport->parent) | 554 | if (gameport->parent) | 
| 548 | gameport->parent->child = gameport; | 555 | gameport->parent->child = gameport; | 
| 549 | 556 | ||
| @@ -558,8 +565,13 @@ static void gameport_add_port(struct gameport *gameport) | |||
| 558 | printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n", | 565 | printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n", | 
| 559 | gameport->name, gameport->phys, gameport->speed); | 566 | gameport->name, gameport->phys, gameport->speed); | 
| 560 | 567 | ||
| 561 | device_add(&gameport->dev); | 568 | error = device_add(&gameport->dev); | 
| 562 | gameport->registered = 1; | 569 | if (error) | 
| 570 | printk(KERN_ERR | ||
| 571 | "gameport: device_add() failed for %s (%s), error: %d\n", | ||
| 572 | gameport->phys, gameport->name, error); | ||
| 573 | else | ||
| 574 | gameport->registered = 1; | ||
| 563 | } | 575 | } | 
| 564 | 576 | ||
| 565 | /* | 577 | /* | 
| @@ -583,10 +595,11 @@ static void gameport_destroy_port(struct gameport *gameport) | |||
| 583 | 595 | ||
| 584 | if (gameport->registered) { | 596 | if (gameport->registered) { | 
| 585 | device_del(&gameport->dev); | 597 | device_del(&gameport->dev); | 
| 586 | list_del_init(&gameport->node); | ||
| 587 | gameport->registered = 0; | 598 | gameport->registered = 0; | 
| 588 | } | 599 | } | 
| 589 | 600 | ||
| 601 | list_del_init(&gameport->node); | ||
| 602 | |||
| 590 | gameport_remove_pending_events(gameport); | 603 | gameport_remove_pending_events(gameport); | 
| 591 | put_device(&gameport->dev); | 604 | put_device(&gameport->dev); | 
| 592 | } | 605 | } | 
| @@ -704,11 +717,22 @@ static int gameport_driver_remove(struct device *dev) | |||
| 704 | } | 717 | } | 
| 705 | 718 | ||
| 706 | static struct bus_type gameport_bus = { | 719 | static struct bus_type gameport_bus = { | 
| 707 | .name = "gameport", | 720 | .name = "gameport", | 
| 708 | .probe = gameport_driver_probe, | 721 | .probe = gameport_driver_probe, | 
| 709 | .remove = gameport_driver_remove, | 722 | .remove = gameport_driver_remove, | 
| 710 | }; | 723 | }; | 
| 711 | 724 | ||
| 725 | static void gameport_add_driver(struct gameport_driver *drv) | ||
| 726 | { | ||
| 727 | int error; | ||
| 728 | |||
| 729 | error = driver_register(&drv->driver); | ||
| 730 | if (error) | ||
| 731 | printk(KERN_ERR | ||
| 732 | "gameport: driver_register() failed for %s, error: %d\n", | ||
| 733 | drv->driver.name, error); | ||
| 734 | } | ||
| 735 | |||
| 712 | void __gameport_register_driver(struct gameport_driver *drv, struct module *owner) | 736 | void __gameport_register_driver(struct gameport_driver *drv, struct module *owner) | 
| 713 | { | 737 | { | 
| 714 | drv->driver.bus = &gameport_bus; | 738 | drv->driver.bus = &gameport_bus; | 
| @@ -778,16 +802,24 @@ void gameport_close(struct gameport *gameport) | |||
| 778 | 802 | ||
| 779 | static int __init gameport_init(void) | 803 | static int __init gameport_init(void) | 
| 780 | { | 804 | { | 
| 781 | gameport_task = kthread_run(gameport_thread, NULL, "kgameportd"); | 805 | int error; | 
| 782 | if (IS_ERR(gameport_task)) { | ||
| 783 | printk(KERN_ERR "gameport: Failed to start kgameportd\n"); | ||
| 784 | return PTR_ERR(gameport_task); | ||
| 785 | } | ||
| 786 | 806 | ||
| 787 | gameport_bus.dev_attrs = gameport_device_attrs; | 807 | gameport_bus.dev_attrs = gameport_device_attrs; | 
| 788 | gameport_bus.drv_attrs = gameport_driver_attrs; | 808 | gameport_bus.drv_attrs = gameport_driver_attrs; | 
| 789 | gameport_bus.match = gameport_bus_match; | 809 | gameport_bus.match = gameport_bus_match; | 
| 790 | bus_register(&gameport_bus); | 810 | error = bus_register(&gameport_bus); | 
| 811 | if (error) { | ||
| 812 | printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error); | ||
| 813 | return error; | ||
| 814 | } | ||
| 815 | |||
| 816 | gameport_task = kthread_run(gameport_thread, NULL, "kgameportd"); | ||
| 817 | if (IS_ERR(gameport_task)) { | ||
| 818 | bus_unregister(&gameport_bus); | ||
| 819 | error = PTR_ERR(gameport_task); | ||
| 820 | printk(KERN_ERR "gameport: Failed to start kgameportd, error: %d\n", error); | ||
| 821 | return error; | ||
| 822 | } | ||
| 791 | 823 | ||
| 792 | return 0; | 824 | return 0; | 
| 793 | } | 825 | } | 
| diff --git a/drivers/input/input.c b/drivers/input/input.c index a90486f5e491..9cb4b9a54f01 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -35,6 +35,16 @@ static LIST_HEAD(input_handler_list); | |||
| 35 | 35 | ||
| 36 | static struct input_handler *input_table[8]; | 36 | static struct input_handler *input_table[8]; | 
| 37 | 37 | ||
| 38 | /** | ||
| 39 | * input_event() - report new input event | ||
| 40 | * @handle: device that generated the event | ||
| 41 | * @type: type of the event | ||
| 42 | * @code: event code | ||
| 43 | * @value: value of the event | ||
| 44 | * | ||
| 45 | * This function should be used by drivers implementing various input devices | ||
| 46 | * See also input_inject_event() | ||
| 47 | */ | ||
| 38 | void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 48 | void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 
| 39 | { | 49 | { | 
| 40 | struct input_handle *handle; | 50 | struct input_handle *handle; | 
| @@ -183,6 +193,23 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in | |||
| 183 | } | 193 | } | 
| 184 | EXPORT_SYMBOL(input_event); | 194 | EXPORT_SYMBOL(input_event); | 
| 185 | 195 | ||
| 196 | /** | ||
| 197 | * input_inject_event() - send input event from input handler | ||
| 198 | * @handle: input handle to send event through | ||
| 199 | * @type: type of the event | ||
| 200 | * @code: event code | ||
| 201 | * @value: value of the event | ||
| 202 | * | ||
| 203 | * Similar to input_event() but will ignore event if device is "grabbed" and handle | ||
| 204 | * injecting event is not the one that owns the device. | ||
| 205 | */ | ||
| 206 | void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) | ||
| 207 | { | ||
| 208 | if (!handle->dev->grab || handle->dev->grab == handle) | ||
| 209 | input_event(handle->dev, type, code, value); | ||
| 210 | } | ||
| 211 | EXPORT_SYMBOL(input_inject_event); | ||
| 212 | |||
| 186 | static void input_repeat_key(unsigned long data) | 213 | static void input_repeat_key(unsigned long data) | 
| 187 | { | 214 | { | 
| 188 | struct input_dev *dev = (void *) data; | 215 | struct input_dev *dev = (void *) data; | 
| @@ -197,15 +224,6 @@ static void input_repeat_key(unsigned long data) | |||
| 197 | mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->rep[REP_PERIOD])); | 224 | mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->rep[REP_PERIOD])); | 
| 198 | } | 225 | } | 
| 199 | 226 | ||
| 200 | int input_accept_process(struct input_handle *handle, struct file *file) | ||
| 201 | { | ||
| 202 | if (handle->dev->accept) | ||
| 203 | return handle->dev->accept(handle->dev, file); | ||
| 204 | |||
| 205 | return 0; | ||
| 206 | } | ||
| 207 | EXPORT_SYMBOL(input_accept_process); | ||
| 208 | |||
| 209 | int input_grab_device(struct input_handle *handle) | 227 | int input_grab_device(struct input_handle *handle) | 
| 210 | { | 228 | { | 
| 211 | if (handle->dev->grab) | 229 | if (handle->dev->grab) | 
| @@ -218,8 +236,15 @@ EXPORT_SYMBOL(input_grab_device); | |||
| 218 | 236 | ||
| 219 | void input_release_device(struct input_handle *handle) | 237 | void input_release_device(struct input_handle *handle) | 
| 220 | { | 238 | { | 
| 221 | if (handle->dev->grab == handle) | 239 | struct input_dev *dev = handle->dev; | 
| 222 | handle->dev->grab = NULL; | 240 | |
| 241 | if (dev->grab == handle) { | ||
| 242 | dev->grab = NULL; | ||
| 243 | |||
| 244 | list_for_each_entry(handle, &dev->h_list, d_node) | ||
| 245 | if (handle->handler->start) | ||
| 246 | handle->handler->start(handle); | ||
| 247 | } | ||
| 223 | } | 248 | } | 
| 224 | EXPORT_SYMBOL(input_release_device); | 249 | EXPORT_SYMBOL(input_release_device); | 
| 225 | 250 | ||
| @@ -963,8 +988,11 @@ int input_register_device(struct input_dev *dev) | |||
| 963 | list_for_each_entry(handler, &input_handler_list, node) | 988 | list_for_each_entry(handler, &input_handler_list, node) | 
| 964 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) | 989 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) | 
| 965 | if ((id = input_match_device(handler->id_table, dev))) | 990 | if ((id = input_match_device(handler->id_table, dev))) | 
| 966 | if ((handle = handler->connect(handler, dev, id))) | 991 | if ((handle = handler->connect(handler, dev, id))) { | 
| 967 | input_link_handle(handle); | 992 | input_link_handle(handle); | 
| 993 | if (handler->start) | ||
| 994 | handler->start(handle); | ||
| 995 | } | ||
| 968 | 996 | ||
| 969 | input_wakeup_procfs_readers(); | 997 | input_wakeup_procfs_readers(); | 
| 970 | 998 | ||
| @@ -1028,8 +1056,11 @@ void input_register_handler(struct input_handler *handler) | |||
| 1028 | list_for_each_entry(dev, &input_dev_list, node) | 1056 | list_for_each_entry(dev, &input_dev_list, node) | 
| 1029 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) | 1057 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) | 
| 1030 | if ((id = input_match_device(handler->id_table, dev))) | 1058 | if ((id = input_match_device(handler->id_table, dev))) | 
| 1031 | if ((handle = handler->connect(handler, dev, id))) | 1059 | if ((handle = handler->connect(handler, dev, id))) { | 
| 1032 | input_link_handle(handle); | 1060 | input_link_handle(handle); | 
| 1061 | if (handler->start) | ||
| 1062 | handler->start(handle); | ||
| 1063 | } | ||
| 1033 | 1064 | ||
| 1034 | input_wakeup_procfs_readers(); | 1065 | input_wakeup_procfs_readers(); | 
| 1035 | } | 1066 | } | 
| diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c index 6d99e3c37884..b4914e7231f8 100644 --- a/drivers/input/joystick/iforce/iforce-main.c +++ b/drivers/input/joystick/iforce/iforce-main.c | |||
| @@ -79,6 +79,7 @@ static struct iforce_device iforce_device[] = { | |||
| 79 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? | 79 | { 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //? | 
| 80 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? | 80 | { 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //? | 
| 81 | { 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? | 81 | { 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //? | 
| 82 | { 0x06d6, 0x29bc, "Trust Force Feedback Race Master", btn_wheel, abs_wheel, ff_iforce }, | ||
| 82 | { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } | 83 | { 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce } | 
| 83 | }; | 84 | }; | 
| 84 | 85 | ||
| @@ -222,22 +223,22 @@ static int iforce_erase_effect(struct input_dev *dev, int effect_id) | |||
| 222 | int err = 0; | 223 | int err = 0; | 
| 223 | struct iforce_core_effect* core_effect; | 224 | struct iforce_core_effect* core_effect; | 
| 224 | 225 | ||
| 225 | /* Check who is trying to erase this effect */ | ||
| 226 | if (iforce->core_effects[effect_id].owner != current->pid) { | ||
| 227 | printk(KERN_WARNING "iforce-main.c: %d tried to erase an effect belonging to %d\n", current->pid, iforce->core_effects[effect_id].owner); | ||
| 228 | return -EACCES; | ||
| 229 | } | ||
| 230 | |||
| 231 | if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX) | 226 | if (effect_id < 0 || effect_id >= FF_EFFECTS_MAX) | 
| 232 | return -EINVAL; | 227 | return -EINVAL; | 
| 233 | 228 | ||
| 234 | core_effect = iforce->core_effects + effect_id; | 229 | core_effect = &iforce->core_effects[effect_id]; | 
| 230 | |||
| 231 | /* Check who is trying to erase this effect */ | ||
| 232 | if (core_effect->owner != current->pid) { | ||
| 233 | printk(KERN_WARNING "iforce-main.c: %d tried to erase an effect belonging to %d\n", current->pid, core_effect->owner); | ||
| 234 | return -EACCES; | ||
| 235 | } | ||
| 235 | 236 | ||
| 236 | if (test_bit(FF_MOD1_IS_USED, core_effect->flags)) | 237 | if (test_bit(FF_MOD1_IS_USED, core_effect->flags)) | 
| 237 | err = release_resource(&(iforce->core_effects[effect_id].mod1_chunk)); | 238 | err = release_resource(&core_effect->mod1_chunk); | 
| 238 | 239 | ||
| 239 | if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags)) | 240 | if (!err && test_bit(FF_MOD2_IS_USED, core_effect->flags)) | 
| 240 | err = release_resource(&(iforce->core_effects[effect_id].mod2_chunk)); | 241 | err = release_resource(&core_effect->mod2_chunk); | 
| 241 | 242 | ||
| 242 | /*TODO: remember to change that if more FF_MOD* bits are added */ | 243 | /*TODO: remember to change that if more FF_MOD* bits are added */ | 
| 243 | core_effect->flags[0] = 0; | 244 | core_effect->flags[0] = 0; | 
| diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index 75eb5ca59992..7a19ee052972 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c | |||
| @@ -50,7 +50,7 @@ MODULE_LICENSE("GPL"); | |||
| 50 | */ | 50 | */ | 
| 51 | 51 | ||
| 52 | #define SPACEBALL_MAX_LENGTH 128 | 52 | #define SPACEBALL_MAX_LENGTH 128 | 
| 53 | #define SPACEBALL_MAX_ID 8 | 53 | #define SPACEBALL_MAX_ID 9 | 
| 54 | 54 | ||
| 55 | #define SPACEBALL_1003 1 | 55 | #define SPACEBALL_1003 1 | 
| 56 | #define SPACEBALL_2003B 3 | 56 | #define SPACEBALL_2003B 3 | 
| diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index ce1f10e8984b..6bfa0cf4b1d2 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
| @@ -482,13 +482,7 @@ out: | |||
| 482 | return IRQ_HANDLED; | 482 | return IRQ_HANDLED; | 
| 483 | } | 483 | } | 
| 484 | 484 | ||
| 485 | /* | 485 | static int atkbd_set_repeat_rate(struct atkbd *atkbd) | 
| 486 | * atkbd_event_work() is used to complete processing of events that | ||
| 487 | * can not be processed by input_event() which is often called from | ||
| 488 | * interrupt context. | ||
| 489 | */ | ||
| 490 | |||
| 491 | static void atkbd_event_work(void *data) | ||
| 492 | { | 486 | { | 
| 493 | const short period[32] = | 487 | const short period[32] = | 
| 494 | { 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125, | 488 | { 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125, | 
| @@ -496,41 +490,64 @@ static void atkbd_event_work(void *data) | |||
| 496 | const short delay[4] = | 490 | const short delay[4] = | 
| 497 | { 250, 500, 750, 1000 }; | 491 | { 250, 500, 750, 1000 }; | 
| 498 | 492 | ||
| 499 | struct atkbd *atkbd = data; | 493 | struct input_dev *dev = atkbd->dev; | 
| 494 | unsigned char param; | ||
| 495 | int i = 0, j = 0; | ||
| 496 | |||
| 497 | while (i < ARRAY_SIZE(period) - 1 && period[i] < dev->rep[REP_PERIOD]) | ||
| 498 | i++; | ||
| 499 | dev->rep[REP_PERIOD] = period[i]; | ||
| 500 | |||
| 501 | while (j < ARRAY_SIZE(period) - 1 && delay[j] < dev->rep[REP_DELAY]) | ||
| 502 | j++; | ||
| 503 | dev->rep[REP_DELAY] = delay[j]; | ||
| 504 | |||
| 505 | param = i | (j << 5); | ||
| 506 | return ps2_command(&atkbd->ps2dev, ¶m, ATKBD_CMD_SETREP); | ||
| 507 | } | ||
| 508 | |||
| 509 | static int atkbd_set_leds(struct atkbd *atkbd) | ||
| 510 | { | ||
| 500 | struct input_dev *dev = atkbd->dev; | 511 | struct input_dev *dev = atkbd->dev; | 
| 501 | unsigned char param[2]; | 512 | unsigned char param[2]; | 
| 502 | int i, j; | ||
| 503 | 513 | ||
| 504 | mutex_lock(&atkbd->event_mutex); | 514 | param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) | 
| 515 | | (test_bit(LED_NUML, dev->led) ? 2 : 0) | ||
| 516 | | (test_bit(LED_CAPSL, dev->led) ? 4 : 0); | ||
| 517 | if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS)) | ||
| 518 | return -1; | ||
| 505 | 519 | ||
| 506 | if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) { | 520 | if (atkbd->extra) { | 
| 507 | param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) | 521 | param[0] = 0; | 
| 508 | | (test_bit(LED_NUML, dev->led) ? 2 : 0) | 522 | param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0) | 
| 509 | | (test_bit(LED_CAPSL, dev->led) ? 4 : 0); | 523 | | (test_bit(LED_SLEEP, dev->led) ? 0x02 : 0) | 
| 510 | ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS); | 524 | | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0) | 
| 511 | 525 | | (test_bit(LED_MISC, dev->led) ? 0x10 : 0) | |
| 512 | if (atkbd->extra) { | 526 | | (test_bit(LED_MUTE, dev->led) ? 0x20 : 0); | 
| 513 | param[0] = 0; | 527 | if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS)) | 
| 514 | param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0) | 528 | return -1; | 
| 515 | | (test_bit(LED_SLEEP, dev->led) ? 0x02 : 0) | ||
| 516 | | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0) | ||
| 517 | | (test_bit(LED_MISC, dev->led) ? 0x10 : 0) | ||
| 518 | | (test_bit(LED_MUTE, dev->led) ? 0x20 : 0); | ||
| 519 | ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS); | ||
| 520 | } | ||
| 521 | } | 529 | } | 
| 522 | 530 | ||
| 523 | if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) { | 531 | return 0; | 
| 524 | i = j = 0; | 532 | } | 
| 525 | while (i < 31 && period[i] < dev->rep[REP_PERIOD]) | 533 | |
| 526 | i++; | 534 | /* | 
| 527 | while (j < 3 && delay[j] < dev->rep[REP_DELAY]) | 535 | * atkbd_event_work() is used to complete processing of events that | 
| 528 | j++; | 536 | * can not be processed by input_event() which is often called from | 
| 529 | dev->rep[REP_PERIOD] = period[i]; | 537 | * interrupt context. | 
| 530 | dev->rep[REP_DELAY] = delay[j]; | 538 | */ | 
| 531 | param[0] = i | (j << 5); | 539 | |
| 532 | ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP); | 540 | static void atkbd_event_work(void *data) | 
| 533 | } | 541 | { | 
| 542 | struct atkbd *atkbd = data; | ||
| 543 | |||
| 544 | mutex_lock(&atkbd->event_mutex); | ||
| 545 | |||
| 546 | if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) | ||
| 547 | atkbd_set_leds(atkbd); | ||
| 548 | |||
| 549 | if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) | ||
| 550 | atkbd_set_repeat_rate(atkbd); | ||
| 534 | 551 | ||
| 535 | mutex_unlock(&atkbd->event_mutex); | 552 | mutex_unlock(&atkbd->event_mutex); | 
| 536 | } | 553 | } | 
| @@ -975,7 +992,6 @@ static int atkbd_reconnect(struct serio *serio) | |||
| 975 | { | 992 | { | 
| 976 | struct atkbd *atkbd = serio_get_drvdata(serio); | 993 | struct atkbd *atkbd = serio_get_drvdata(serio); | 
| 977 | struct serio_driver *drv = serio->drv; | 994 | struct serio_driver *drv = serio->drv; | 
| 978 | unsigned char param[1]; | ||
| 979 | 995 | ||
| 980 | if (!atkbd || !drv) { | 996 | if (!atkbd || !drv) { | 
| 981 | printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); | 997 | printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); | 
| @@ -985,10 +1001,6 @@ static int atkbd_reconnect(struct serio *serio) | |||
| 985 | atkbd_disable(atkbd); | 1001 | atkbd_disable(atkbd); | 
| 986 | 1002 | ||
| 987 | if (atkbd->write) { | 1003 | if (atkbd->write) { | 
| 988 | param[0] = (test_bit(LED_SCROLLL, atkbd->dev->led) ? 1 : 0) | ||
| 989 | | (test_bit(LED_NUML, atkbd->dev->led) ? 2 : 0) | ||
| 990 | | (test_bit(LED_CAPSL, atkbd->dev->led) ? 4 : 0); | ||
| 991 | |||
| 992 | if (atkbd_probe(atkbd)) | 1004 | if (atkbd_probe(atkbd)) | 
| 993 | return -1; | 1005 | return -1; | 
| 994 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) | 1006 | if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) | 
| @@ -996,8 +1008,13 @@ static int atkbd_reconnect(struct serio *serio) | |||
| 996 | 1008 | ||
| 997 | atkbd_activate(atkbd); | 1009 | atkbd_activate(atkbd); | 
| 998 | 1010 | ||
| 999 | if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS)) | 1011 | /* | 
| 1000 | return -1; | 1012 | * Restore repeat rate and LEDs (that were reset by atkbd_activate) | 
| 1013 | * to pre-resume state | ||
| 1014 | */ | ||
| 1015 | if (!atkbd->softrepeat) | ||
| 1016 | atkbd_set_repeat_rate(atkbd); | ||
| 1017 | atkbd_set_leds(atkbd); | ||
| 1001 | } | 1018 | } | 
| 1002 | 1019 | ||
| 1003 | atkbd_enable(atkbd); | 1020 | atkbd_enable(atkbd); | 
| diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index ccf0faeee5c1..a8efc1af36cb 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c | |||
| @@ -94,7 +94,7 @@ static void call_bios(struct regs *regs) | |||
| 94 | 94 | ||
| 95 | static ssize_t __init locate_wistron_bios(void __iomem *base) | 95 | static ssize_t __init locate_wistron_bios(void __iomem *base) | 
| 96 | { | 96 | { | 
| 97 | static const unsigned char __initdata signature[] = | 97 | static unsigned char __initdata signature[] = | 
| 98 | { 0x42, 0x21, 0x55, 0x30 }; | 98 | { 0x42, 0x21, 0x55, 0x30 }; | 
| 99 | ssize_t offset; | 99 | ssize_t offset; | 
| 100 | 100 | ||
| @@ -259,11 +259,11 @@ static int __init dmi_matched(struct dmi_system_id *dmi) | |||
| 259 | return 1; | 259 | return 1; | 
| 260 | } | 260 | } | 
| 261 | 261 | ||
| 262 | static struct key_entry keymap_empty[] = { | 262 | static struct key_entry keymap_empty[] __initdata = { | 
| 263 | { KE_END, 0 } | 263 | { KE_END, 0 } | 
| 264 | }; | 264 | }; | 
| 265 | 265 | ||
| 266 | static struct key_entry keymap_fs_amilo_pro_v2000[] = { | 266 | static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = { | 
| 267 | { KE_KEY, 0x01, KEY_HELP }, | 267 | { KE_KEY, 0x01, KEY_HELP }, | 
| 268 | { KE_KEY, 0x11, KEY_PROG1 }, | 268 | { KE_KEY, 0x11, KEY_PROG1 }, | 
| 269 | { KE_KEY, 0x12, KEY_PROG2 }, | 269 | { KE_KEY, 0x12, KEY_PROG2 }, | 
| @@ -273,7 +273,7 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] = { | |||
| 273 | { KE_END, 0 } | 273 | { KE_END, 0 } | 
| 274 | }; | 274 | }; | 
| 275 | 275 | ||
| 276 | static struct key_entry keymap_fujitsu_n3510[] = { | 276 | static struct key_entry keymap_fujitsu_n3510[] __initdata = { | 
| 277 | { KE_KEY, 0x11, KEY_PROG1 }, | 277 | { KE_KEY, 0x11, KEY_PROG1 }, | 
| 278 | { KE_KEY, 0x12, KEY_PROG2 }, | 278 | { KE_KEY, 0x12, KEY_PROG2 }, | 
| 279 | { KE_KEY, 0x36, KEY_WWW }, | 279 | { KE_KEY, 0x36, KEY_WWW }, | 
| @@ -285,7 +285,7 @@ static struct key_entry keymap_fujitsu_n3510[] = { | |||
| 285 | { KE_END, 0 } | 285 | { KE_END, 0 } | 
| 286 | }; | 286 | }; | 
| 287 | 287 | ||
| 288 | static struct key_entry keymap_wistron_ms2111[] = { | 288 | static struct key_entry keymap_wistron_ms2111[] __initdata = { | 
| 289 | { KE_KEY, 0x11, KEY_PROG1 }, | 289 | { KE_KEY, 0x11, KEY_PROG1 }, | 
| 290 | { KE_KEY, 0x12, KEY_PROG2 }, | 290 | { KE_KEY, 0x12, KEY_PROG2 }, | 
| 291 | { KE_KEY, 0x13, KEY_PROG3 }, | 291 | { KE_KEY, 0x13, KEY_PROG3 }, | 
| @@ -294,7 +294,7 @@ static struct key_entry keymap_wistron_ms2111[] = { | |||
| 294 | { KE_END, 0 } | 294 | { KE_END, 0 } | 
| 295 | }; | 295 | }; | 
| 296 | 296 | ||
| 297 | static struct key_entry keymap_wistron_ms2141[] = { | 297 | static struct key_entry keymap_wistron_ms2141[] __initdata = { | 
| 298 | { KE_KEY, 0x11, KEY_PROG1 }, | 298 | { KE_KEY, 0x11, KEY_PROG1 }, | 
| 299 | { KE_KEY, 0x12, KEY_PROG2 }, | 299 | { KE_KEY, 0x12, KEY_PROG2 }, | 
| 300 | { KE_WIFI, 0x30, 0 }, | 300 | { KE_WIFI, 0x30, 0 }, | 
| @@ -307,7 +307,7 @@ static struct key_entry keymap_wistron_ms2141[] = { | |||
| 307 | { KE_END, 0 } | 307 | { KE_END, 0 } | 
| 308 | }; | 308 | }; | 
| 309 | 309 | ||
| 310 | static struct key_entry keymap_acer_aspire_1500[] = { | 310 | static struct key_entry keymap_acer_aspire_1500[] __initdata = { | 
| 311 | { KE_KEY, 0x11, KEY_PROG1 }, | 311 | { KE_KEY, 0x11, KEY_PROG1 }, | 
| 312 | { KE_KEY, 0x12, KEY_PROG2 }, | 312 | { KE_KEY, 0x12, KEY_PROG2 }, | 
| 313 | { KE_WIFI, 0x30, 0 }, | 313 | { KE_WIFI, 0x30, 0 }, | 
| @@ -317,7 +317,7 @@ static struct key_entry keymap_acer_aspire_1500[] = { | |||
| 317 | { KE_END, 0 } | 317 | { KE_END, 0 } | 
| 318 | }; | 318 | }; | 
| 319 | 319 | ||
| 320 | static struct key_entry keymap_acer_travelmate_240[] = { | 320 | static struct key_entry keymap_acer_travelmate_240[] __initdata = { | 
| 321 | { KE_KEY, 0x31, KEY_MAIL }, | 321 | { KE_KEY, 0x31, KEY_MAIL }, | 
| 322 | { KE_KEY, 0x36, KEY_WWW }, | 322 | { KE_KEY, 0x36, KEY_WWW }, | 
| 323 | { KE_KEY, 0x11, KEY_PROG1 }, | 323 | { KE_KEY, 0x11, KEY_PROG1 }, | 
| @@ -327,7 +327,7 @@ static struct key_entry keymap_acer_travelmate_240[] = { | |||
| 327 | { KE_END, 0 } | 327 | { KE_END, 0 } | 
| 328 | }; | 328 | }; | 
| 329 | 329 | ||
| 330 | static struct key_entry keymap_aopen_1559as[] = { | 330 | static struct key_entry keymap_aopen_1559as[] __initdata = { | 
| 331 | { KE_KEY, 0x01, KEY_HELP }, | 331 | { KE_KEY, 0x01, KEY_HELP }, | 
| 332 | { KE_KEY, 0x06, KEY_PROG3 }, | 332 | { KE_KEY, 0x06, KEY_PROG3 }, | 
| 333 | { KE_KEY, 0x11, KEY_PROG1 }, | 333 | { KE_KEY, 0x11, KEY_PROG1 }, | 
| @@ -343,7 +343,7 @@ static struct key_entry keymap_aopen_1559as[] = { | |||
| 343 | * a list of buttons and their key codes (reported when loading this module | 343 | * a list of buttons and their key codes (reported when loading this module | 
| 344 | * with force=1) and the output of dmidecode to $MODULE_AUTHOR. | 344 | * with force=1) and the output of dmidecode to $MODULE_AUTHOR. | 
| 345 | */ | 345 | */ | 
| 346 | static struct dmi_system_id dmi_ids[] = { | 346 | static struct dmi_system_id dmi_ids[] __initdata = { | 
| 347 | { | 347 | { | 
| 348 | .callback = dmi_matched, | 348 | .callback = dmi_matched, | 
| 349 | .ident = "Fujitsu-Siemens Amilo Pro V2000", | 349 | .ident = "Fujitsu-Siemens Amilo Pro V2000", | 
| diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 2f0d28840810..54b696cfe1e3 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
| @@ -238,8 +238,7 @@ static struct ps2pp_info *get_model_info(unsigned char model) | |||
| 238 | { 100, PS2PP_KIND_MX, /* MX510 */ | 238 | { 100, PS2PP_KIND_MX, /* MX510 */ | 
| 239 | PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | | 239 | PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | | 
| 240 | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, | 240 | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, | 
| 241 | { 111, PS2PP_KIND_MX, /* MX300 */ | 241 | { 111, PS2PP_KIND_MX, PS2PP_WHEEL | PS2PP_SIDE_BTN }, /* MX300 reports task button as side */ | 
| 242 | PS2PP_WHEEL | PS2PP_EXTRA_BTN | PS2PP_TASK_BTN }, | ||
| 243 | { 112, PS2PP_KIND_MX, /* MX500 */ | 242 | { 112, PS2PP_KIND_MX, /* MX500 */ | 
| 244 | PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | | 243 | PS2PP_WHEEL | PS2PP_SIDE_BTN | PS2PP_TASK_BTN | | 
| 245 | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, | 244 | PS2PP_EXTRA_BTN | PS2PP_NAV_BTN }, | 
| diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 6d9ec9ab1b90..ae5871a0e060 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
| @@ -183,21 +183,26 @@ static struct attribute_group trackpoint_attr_group = { | |||
| 183 | .attrs = trackpoint_attrs, | 183 | .attrs = trackpoint_attrs, | 
| 184 | }; | 184 | }; | 
| 185 | 185 | ||
| 186 | static void trackpoint_disconnect(struct psmouse *psmouse) | 186 | static int trackpoint_start_protocol(struct psmouse *psmouse, unsigned char *firmware_id) | 
| 187 | { | 187 | { | 
| 188 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group); | 188 | unsigned char param[2] = { 0 }; | 
| 189 | 189 | ||
| 190 | kfree(psmouse->private); | 190 | if (ps2_command(&psmouse->ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID))) | 
| 191 | psmouse->private = NULL; | 191 | return -1; | 
| 192 | |||
| 193 | if (param[0] != TP_MAGIC_IDENT) | ||
| 194 | return -1; | ||
| 195 | |||
| 196 | if (firmware_id) | ||
| 197 | *firmware_id = param[1]; | ||
| 198 | |||
| 199 | return 0; | ||
| 192 | } | 200 | } | 
| 193 | 201 | ||
| 194 | static int trackpoint_sync(struct psmouse *psmouse) | 202 | static int trackpoint_sync(struct psmouse *psmouse) | 
| 195 | { | 203 | { | 
| 196 | unsigned char toggle; | ||
| 197 | struct trackpoint_data *tp = psmouse->private; | 204 | struct trackpoint_data *tp = psmouse->private; | 
| 198 | 205 | unsigned char toggle; | |
| 199 | if (!tp) | ||
| 200 | return -1; | ||
| 201 | 206 | ||
| 202 | /* Disable features that may make device unusable with this driver */ | 207 | /* Disable features that may make device unusable with this driver */ | 
| 203 | trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_TWOHAND, &toggle); | 208 | trackpoint_read(&psmouse->ps2dev, TP_TOGGLE_TWOHAND, &toggle); | 
| @@ -263,27 +268,38 @@ static void trackpoint_defaults(struct trackpoint_data *tp) | |||
| 263 | tp->ext_dev = TP_DEF_EXT_DEV; | 268 | tp->ext_dev = TP_DEF_EXT_DEV; | 
| 264 | } | 269 | } | 
| 265 | 270 | ||
| 271 | static void trackpoint_disconnect(struct psmouse *psmouse) | ||
| 272 | { | ||
| 273 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group); | ||
| 274 | |||
| 275 | kfree(psmouse->private); | ||
| 276 | psmouse->private = NULL; | ||
| 277 | } | ||
| 278 | |||
| 279 | static int trackpoint_reconnect(struct psmouse *psmouse) | ||
| 280 | { | ||
| 281 | if (trackpoint_start_protocol(psmouse, NULL)) | ||
| 282 | return -1; | ||
| 283 | |||
| 284 | if (trackpoint_sync(psmouse)) | ||
| 285 | return -1; | ||
| 286 | |||
| 287 | return 0; | ||
| 288 | } | ||
| 289 | |||
| 266 | int trackpoint_detect(struct psmouse *psmouse, int set_properties) | 290 | int trackpoint_detect(struct psmouse *psmouse, int set_properties) | 
| 267 | { | 291 | { | 
| 268 | struct trackpoint_data *priv; | 292 | struct trackpoint_data *priv; | 
| 269 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 293 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 
| 270 | unsigned char firmware_id; | 294 | unsigned char firmware_id; | 
| 271 | unsigned char button_info; | 295 | unsigned char button_info; | 
| 272 | unsigned char param[2]; | ||
| 273 | |||
| 274 | param[0] = param[1] = 0; | ||
| 275 | 296 | ||
| 276 | if (ps2_command(ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID))) | 297 | if (trackpoint_start_protocol(psmouse, &firmware_id)) | 
| 277 | return -1; | ||
| 278 | |||
| 279 | if (param[0] != TP_MAGIC_IDENT) | ||
| 280 | return -1; | 298 | return -1; | 
| 281 | 299 | ||
| 282 | if (!set_properties) | 300 | if (!set_properties) | 
| 283 | return 0; | 301 | return 0; | 
| 284 | 302 | ||
| 285 | firmware_id = param[1]; | ||
| 286 | |||
| 287 | if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) { | 303 | if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) { | 
| 288 | printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n"); | 304 | printk(KERN_WARNING "trackpoint.c: failed to get extended button data\n"); | 
| 289 | button_info = 0; | 305 | button_info = 0; | 
| @@ -296,7 +312,7 @@ int trackpoint_detect(struct psmouse *psmouse, int set_properties) | |||
| 296 | psmouse->vendor = "IBM"; | 312 | psmouse->vendor = "IBM"; | 
| 297 | psmouse->name = "TrackPoint"; | 313 | psmouse->name = "TrackPoint"; | 
| 298 | 314 | ||
| 299 | psmouse->reconnect = trackpoint_sync; | 315 | psmouse->reconnect = trackpoint_reconnect; | 
| 300 | psmouse->disconnect = trackpoint_disconnect; | 316 | psmouse->disconnect = trackpoint_disconnect; | 
| 301 | 317 | ||
| 302 | trackpoint_defaults(priv); | 318 | trackpoint_defaults(priv); | 
| diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index 61a6f977846f..ed202f2f251a 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
| @@ -177,6 +177,11 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) | |||
| 177 | return -1; | 177 | return -1; | 
| 178 | } | 178 | } | 
| 179 | 179 | ||
| 180 | if (send && !param) { | ||
| 181 | WARN_ON(1); | ||
| 182 | return -1; | ||
| 183 | } | ||
| 184 | |||
| 180 | mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING); | 185 | mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING); | 
| 181 | 186 | ||
| 182 | serio_pause_rx(ps2dev->serio); | 187 | serio_pause_rx(ps2dev->serio); | 
| diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 6521034bc933..3e76ad71c9a0 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
| @@ -62,6 +62,7 @@ static LIST_HEAD(serio_list); | |||
| 62 | 62 | ||
| 63 | static struct bus_type serio_bus; | 63 | static struct bus_type serio_bus; | 
| 64 | 64 | ||
| 65 | static void serio_add_driver(struct serio_driver *drv); | ||
| 65 | static void serio_add_port(struct serio *serio); | 66 | static void serio_add_port(struct serio *serio); | 
| 66 | static void serio_destroy_port(struct serio *serio); | 67 | static void serio_destroy_port(struct serio *serio); | 
| 67 | static void serio_reconnect_port(struct serio *serio); | 68 | static void serio_reconnect_port(struct serio *serio); | 
| @@ -140,8 +141,14 @@ static void serio_release_driver(struct serio *serio) | |||
| 140 | 141 | ||
| 141 | static void serio_find_driver(struct serio *serio) | 142 | static void serio_find_driver(struct serio *serio) | 
| 142 | { | 143 | { | 
| 144 | int error; | ||
| 145 | |||
| 143 | down_write(&serio_bus.subsys.rwsem); | 146 | down_write(&serio_bus.subsys.rwsem); | 
| 144 | device_attach(&serio->dev); | 147 | error = device_attach(&serio->dev); | 
| 148 | if (error < 0) | ||
| 149 | printk(KERN_WARNING | ||
| 150 | "serio: device_attach() failed for %s (%s), error: %d\n", | ||
| 151 | serio->phys, serio->name, error); | ||
| 145 | up_write(&serio_bus.subsys.rwsem); | 152 | up_write(&serio_bus.subsys.rwsem); | 
| 146 | } | 153 | } | 
| 147 | 154 | ||
| @@ -272,7 +279,6 @@ static struct serio_event *serio_get_event(void) | |||
| 272 | static void serio_handle_event(void) | 279 | static void serio_handle_event(void) | 
| 273 | { | 280 | { | 
| 274 | struct serio_event *event; | 281 | struct serio_event *event; | 
| 275 | struct serio_driver *serio_drv; | ||
| 276 | 282 | ||
| 277 | mutex_lock(&serio_mutex); | 283 | mutex_lock(&serio_mutex); | 
| 278 | 284 | ||
| @@ -304,8 +310,7 @@ static void serio_handle_event(void) | |||
| 304 | break; | 310 | break; | 
| 305 | 311 | ||
| 306 | case SERIO_REGISTER_DRIVER: | 312 | case SERIO_REGISTER_DRIVER: | 
| 307 | serio_drv = event->object; | 313 | serio_add_driver(event->object); | 
| 308 | driver_register(&serio_drv->driver); | ||
| 309 | break; | 314 | break; | 
| 310 | 315 | ||
| 311 | default: | 316 | default: | 
| @@ -525,6 +530,7 @@ static void serio_init_port(struct serio *serio) | |||
| 525 | 530 | ||
| 526 | __module_get(THIS_MODULE); | 531 | __module_get(THIS_MODULE); | 
| 527 | 532 | ||
| 533 | INIT_LIST_HEAD(&serio->node); | ||
| 528 | spin_lock_init(&serio->lock); | 534 | spin_lock_init(&serio->lock); | 
| 529 | mutex_init(&serio->drv_mutex); | 535 | mutex_init(&serio->drv_mutex); | 
| 530 | device_initialize(&serio->dev); | 536 | device_initialize(&serio->dev); | 
| @@ -542,6 +548,8 @@ static void serio_init_port(struct serio *serio) | |||
| 542 | */ | 548 | */ | 
| 543 | static void serio_add_port(struct serio *serio) | 549 | static void serio_add_port(struct serio *serio) | 
| 544 | { | 550 | { | 
| 551 | int error; | ||
| 552 | |||
| 545 | if (serio->parent) { | 553 | if (serio->parent) { | 
| 546 | serio_pause_rx(serio->parent); | 554 | serio_pause_rx(serio->parent); | 
| 547 | serio->parent->child = serio; | 555 | serio->parent->child = serio; | 
| @@ -551,9 +559,19 @@ static void serio_add_port(struct serio *serio) | |||
| 551 | list_add_tail(&serio->node, &serio_list); | 559 | list_add_tail(&serio->node, &serio_list); | 
| 552 | if (serio->start) | 560 | if (serio->start) | 
| 553 | serio->start(serio); | 561 | serio->start(serio); | 
| 554 | device_add(&serio->dev); | 562 | error = device_add(&serio->dev); | 
| 555 | sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); | 563 | if (error) | 
| 556 | serio->registered = 1; | 564 | printk(KERN_ERR | 
| 565 | "serio: device_add() failed for %s (%s), error: %d\n", | ||
| 566 | serio->phys, serio->name, error); | ||
| 567 | else { | ||
| 568 | serio->registered = 1; | ||
| 569 | error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); | ||
| 570 | if (error) | ||
| 571 | printk(KERN_ERR | ||
| 572 | "serio: sysfs_create_group() failed for %s (%s), error: %d\n", | ||
| 573 | serio->phys, serio->name, error); | ||
| 574 | } | ||
| 557 | } | 575 | } | 
| 558 | 576 | ||
| 559 | /* | 577 | /* | 
| @@ -583,10 +601,10 @@ static void serio_destroy_port(struct serio *serio) | |||
| 583 | if (serio->registered) { | 601 | if (serio->registered) { | 
| 584 | sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); | 602 | sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); | 
| 585 | device_del(&serio->dev); | 603 | device_del(&serio->dev); | 
| 586 | list_del_init(&serio->node); | ||
| 587 | serio->registered = 0; | 604 | serio->registered = 0; | 
| 588 | } | 605 | } | 
| 589 | 606 | ||
| 607 | list_del_init(&serio->node); | ||
| 590 | serio_remove_pending_events(serio); | 608 | serio_remove_pending_events(serio); | 
| 591 | put_device(&serio->dev); | 609 | put_device(&serio->dev); | 
| 592 | } | 610 | } | 
| @@ -756,6 +774,17 @@ static struct bus_type serio_bus = { | |||
| 756 | .remove = serio_driver_remove, | 774 | .remove = serio_driver_remove, | 
| 757 | }; | 775 | }; | 
| 758 | 776 | ||
| 777 | static void serio_add_driver(struct serio_driver *drv) | ||
| 778 | { | ||
| 779 | int error; | ||
| 780 | |||
| 781 | error = driver_register(&drv->driver); | ||
| 782 | if (error) | ||
| 783 | printk(KERN_ERR | ||
| 784 | "serio: driver_register() failed for %s, error: %d\n", | ||
| 785 | drv->driver.name, error); | ||
| 786 | } | ||
| 787 | |||
| 759 | void __serio_register_driver(struct serio_driver *drv, struct module *owner) | 788 | void __serio_register_driver(struct serio_driver *drv, struct module *owner) | 
| 760 | { | 789 | { | 
| 761 | drv->driver.bus = &serio_bus; | 790 | drv->driver.bus = &serio_bus; | 
| @@ -903,18 +932,26 @@ irqreturn_t serio_interrupt(struct serio *serio, | |||
| 903 | 932 | ||
| 904 | static int __init serio_init(void) | 933 | static int __init serio_init(void) | 
| 905 | { | 934 | { | 
| 906 | serio_task = kthread_run(serio_thread, NULL, "kseriod"); | 935 | int error; | 
| 907 | if (IS_ERR(serio_task)) { | ||
| 908 | printk(KERN_ERR "serio: Failed to start kseriod\n"); | ||
| 909 | return PTR_ERR(serio_task); | ||
| 910 | } | ||
| 911 | 936 | ||
| 912 | serio_bus.dev_attrs = serio_device_attrs; | 937 | serio_bus.dev_attrs = serio_device_attrs; | 
| 913 | serio_bus.drv_attrs = serio_driver_attrs; | 938 | serio_bus.drv_attrs = serio_driver_attrs; | 
| 914 | serio_bus.match = serio_bus_match; | 939 | serio_bus.match = serio_bus_match; | 
| 915 | serio_bus.uevent = serio_uevent; | 940 | serio_bus.uevent = serio_uevent; | 
| 916 | serio_bus.resume = serio_resume; | 941 | serio_bus.resume = serio_resume; | 
| 917 | bus_register(&serio_bus); | 942 | error = bus_register(&serio_bus); | 
| 943 | if (error) { | ||
| 944 | printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); | ||
| 945 | return error; | ||
| 946 | } | ||
| 947 | |||
| 948 | serio_task = kthread_run(serio_thread, NULL, "kseriod"); | ||
| 949 | if (IS_ERR(serio_task)) { | ||
| 950 | bus_unregister(&serio_bus); | ||
| 951 | error = PTR_ERR(serio_task); | ||
| 952 | printk(KERN_ERR "serio: Failed to start kseriod, error: %d\n", error); | ||
| 953 | return error; | ||
| 954 | } | ||
| 918 | 955 | ||
| 919 | return 0; | 956 | return 0; | 
| 920 | } | 957 | } | 
