diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c index deaf232078122450ab31ccedf6a48515305012bd..3416f69302cd44bb440ffbc92527cea3435acb94 100644 --- a/drivers/hid/hid-wiimote.c +++ b/drivers/hid/hid-wiimote.c @@ -10,6 +10,7 @@ * any later version. */ +#include #include #include #include @@ -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;