Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HID: magicmouse: fix race between input_register() and probe()

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

Cc: stable@vger.kernel.org
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>

authored by

Benjamin Tissoires and committed by
Jiri Kosina
f1a9a149 30b29537

+20 -9
+20 -9
drivers/hid/hid-magicmouse.c
··· 462 462 return 0; 463 463 } 464 464 465 + static void magicmouse_input_configured(struct hid_device *hdev, 466 + struct hid_input *hi) 467 + 468 + { 469 + struct magicmouse_sc *msc = hid_get_drvdata(hdev); 470 + 471 + int ret = magicmouse_setup_input(msc->input, hdev); 472 + if (ret) { 473 + hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); 474 + /* clean msc->input to notify probe() of the failure */ 475 + msc->input = NULL; 476 + } 477 + } 478 + 479 + 465 480 static int magicmouse_probe(struct hid_device *hdev, 466 481 const struct hid_device_id *id) 467 482 { ··· 508 493 goto err_free; 509 494 } 510 495 511 - /* We do this after hid-input is done parsing reports so that 512 - * hid-input uses the most natural button and axis IDs. 513 - */ 514 - if (msc->input) { 515 - ret = magicmouse_setup_input(msc->input, hdev); 516 - if (ret) { 517 - hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); 518 - goto err_stop_hw; 519 - } 496 + if (!msc->input) { 497 + hid_err(hdev, "magicmouse input not registered\n"); 498 + ret = -ENOMEM; 499 + goto err_stop_hw; 520 500 } 521 501 522 502 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) ··· 578 568 .remove = magicmouse_remove, 579 569 .raw_event = magicmouse_raw_event, 580 570 .input_mapping = magicmouse_input_mapping, 571 + .input_configured = magicmouse_input_configured, 581 572 }; 582 573 module_hid_driver(magicmouse_driver); 583 574