summaryrefslogtreecommitdiff
path: root/drivers/hid/hid-wiimote.h
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-10-02 15:47:28 +0400
committerJiri Kosina <jkosina@suse.cz>2013-10-07 19:08:26 +0400
commitf50f9aabf32db7414551ffdfdccc71be5f3d6e7d (patch)
tree1d624ee07097e1548551f77dfa537cff6400619b /drivers/hid/hid-wiimote.h
parent7da7cbbbeb60e0939fecdf9723b388136c175e5c (diff)
downloadlinux-f50f9aabf32db7414551ffdfdccc71be5f3d6e7d.tar.xz
HID: wiimote: fix FF deadlock
The input core has an internal spinlock that is acquired during event injection via input_event() and friends but also held during FF callbacks. That means, there is no way to share a lock between event-injection and FF handling. Unfortunately, this is what is required for wiimote state tracking and what we do with state.lock and input->lock. This deadlock can be triggered when using continuous data reporting and FF on a wiimote device at the same time. I takes me at least 30m of stress-testing to trigger it but users reported considerably shorter times (http://bpaste.net/show/132504/) when using some gaming-console emulators. The real problem is that we have two copies of internal state, one in the wiimote objects and the other in the input device. As the input-lock is not supposed to be accessed from outside of input-core, we have no other chance than offloading FF handling into a worker. This actually works pretty nice and also allows to implictly merge fast rumble changes into a single request. Due to the 3-layered workers (rumble+queue+l2cap) this might reduce FF responsiveness. Initial tests were fine so lets fix the race first and if it turns out to be too slow we can always handle FF out-of-band and skip the queue-worker. Cc: <stable@vger.kernel.org> # 3.11+ Reported-by: Thomas Schneider Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-wiimote.h')
-rw-r--r--drivers/hid/hid-wiimote.h4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
index f1474f372c0b..75db0c400037 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -133,13 +133,15 @@ struct wiimote_state {
__u8 *cmd_read_buf;
__u8 cmd_read_size;
- /* calibration data */
+ /* calibration/cache data */
__u16 calib_bboard[4][3];
+ __u8 cache_rumble;
};
struct wiimote_data {
struct hid_device *hdev;
struct input_dev *input;
+ struct work_struct rumble_worker;
struct led_classdev *leds[4];
struct input_dev *accel;
struct input_dev *ir;