| From f1a9a149abc86903e81dd1b2e720f3f89874384b Mon Sep 17 00:00:00 2001 |
| From: Benjamin Tissoires <benjamin.tissoires@redhat.com> |
| Date: Tue, 2 Apr 2013 11:11:52 +0200 |
| Subject: HID: magicmouse: fix race between input_register() and probe() |
| |
| From: Benjamin Tissoires <benjamin.tissoires@redhat.com> |
| |
| commit f1a9a149abc86903e81dd1b2e720f3f89874384b upstream. |
| |
| Since kernel 3.7, it appears that the input registration occured before |
| the end of magicmouse_setup_input(). This is shown by receiving a lot of |
| "EV_SYN SYN_REPORT 1" instead of normal "EV_SYN SYN_REPORT 0". |
| This value means that the output buffer is full, and the user space |
| is loosing events. |
| |
| Using .input_configured guarantees that the race is not occuring, and that |
| the call of "input_set_events_per_packet(input, 60)" is taken into account |
| by input_register(). |
| |
| Fixes: |
| https://bugzilla.redhat.com/show_bug.cgi?id=908604 |
| |
| Reported-and-Tested-By: Clarke Wixon <cwixon@usa.net> |
| Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> |
| Signed-off-by: Jiri Kosina <jkosina@suse.cz> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/hid/hid-magicmouse.c | 29 ++++++++++++++++++++--------- |
| 1 file changed, 20 insertions(+), 9 deletions(-) |
| |
| --- a/drivers/hid/hid-magicmouse.c |
| +++ b/drivers/hid/hid-magicmouse.c |
| @@ -462,6 +462,21 @@ static int magicmouse_input_mapping(stru |
| return 0; |
| } |
| |
| +static void magicmouse_input_configured(struct hid_device *hdev, |
| + struct hid_input *hi) |
| + |
| +{ |
| + struct magicmouse_sc *msc = hid_get_drvdata(hdev); |
| + |
| + int ret = magicmouse_setup_input(msc->input, hdev); |
| + if (ret) { |
| + hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); |
| + /* clean msc->input to notify probe() of the failure */ |
| + msc->input = NULL; |
| + } |
| +} |
| + |
| + |
| static int magicmouse_probe(struct hid_device *hdev, |
| const struct hid_device_id *id) |
| { |
| @@ -493,15 +508,10 @@ static int magicmouse_probe(struct hid_d |
| goto err_free; |
| } |
| |
| - /* We do this after hid-input is done parsing reports so that |
| - * hid-input uses the most natural button and axis IDs. |
| - */ |
| - if (msc->input) { |
| - ret = magicmouse_setup_input(msc->input, hdev); |
| - if (ret) { |
| - hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); |
| - goto err_stop_hw; |
| - } |
| + if (!msc->input) { |
| + hid_err(hdev, "magicmouse input not registered\n"); |
| + ret = -ENOMEM; |
| + goto err_stop_hw; |
| } |
| |
| if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) |
| @@ -568,6 +578,7 @@ static struct hid_driver magicmouse_driv |
| .remove = magicmouse_remove, |
| .raw_event = magicmouse_raw_event, |
| .input_mapping = magicmouse_input_mapping, |
| + .input_configured = magicmouse_input_configured, |
| }; |
| |
| static int __init magicmouse_init(void) |