diff options
-rw-r--r-- | drivers/hid/hid-wiimote.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c index deaf23207812..3416f69302cd 100644 --- a/drivers/hid/hid-wiimote.c +++ b/drivers/hid/hid-wiimote.c @@ -10,6 +10,7 @@ * any later version. */ +#include <linux/atomic.h> #include <linux/device.h> #include <linux/hid.h> #include <linux/input.h> @@ -20,6 +21,7 @@ #define WIIMOTE_NAME "Nintendo Wii Remote" struct wiimote_data { + atomic_t ready; struct hid_device *hdev; struct input_dev *input; }; @@ -27,12 +29,26 @@ struct wiimote_data { static int wiimote_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { + struct wiimote_data *wdata = input_get_drvdata(dev); + + if (!atomic_read(&wdata->ready)) + return -EBUSY; + /* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */ + smp_rmb(); + return 0; } static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, u8 *raw_data, int size) { + struct wiimote_data *wdata = hid_get_drvdata(hdev); + + if (!atomic_read(&wdata->ready)) + return -EBUSY; + /* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */ + smp_rmb(); + if (size < 1) return -EINVAL; @@ -103,6 +119,9 @@ static int wiimote_hid_probe(struct hid_device *hdev, goto err_stop; } + /* smp_wmb: Write wdata->xy first before wdata->ready is set to 1 */ + smp_wmb(); + atomic_set(&wdata->ready, 1); hid_info(hdev, "New device registered\n"); return 0; |