diff options
Diffstat (limited to 'drivers/hid/hid-wiimote.h')
-rw-r--r-- | drivers/hid/hid-wiimote.h | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h index 301607da7715..34417021606e 100644 --- a/drivers/hid/hid-wiimote.h +++ b/drivers/hid/hid-wiimote.h | |||
@@ -195,6 +195,16 @@ static inline void wiimote_cmd_complete(struct wiimote_data *wdata) | |||
195 | complete(&wdata->state.ready); | 195 | complete(&wdata->state.ready); |
196 | } | 196 | } |
197 | 197 | ||
198 | /* requires the state.lock spinlock to be held */ | ||
199 | static inline void wiimote_cmd_abort(struct wiimote_data *wdata) | ||
200 | { | ||
201 | /* Abort synchronous request by waking up the sleeping caller. But | ||
202 | * reset the state.cmd field to an invalid value so no further event | ||
203 | * handlers will work with it. */ | ||
204 | wdata->state.cmd = WIIPROTO_REQ_MAX; | ||
205 | complete(&wdata->state.ready); | ||
206 | } | ||
207 | |||
198 | static inline int wiimote_cmd_acquire(struct wiimote_data *wdata) | 208 | static inline int wiimote_cmd_acquire(struct wiimote_data *wdata) |
199 | { | 209 | { |
200 | return mutex_lock_interruptible(&wdata->state.sync) ? -ERESTARTSYS : 0; | 210 | return mutex_lock_interruptible(&wdata->state.sync) ? -ERESTARTSYS : 0; |
@@ -223,11 +233,17 @@ static inline int wiimote_cmd_wait(struct wiimote_data *wdata) | |||
223 | { | 233 | { |
224 | int ret; | 234 | int ret; |
225 | 235 | ||
236 | /* The completion acts as implicit memory barrier so we can safely | ||
237 | * assume that state.cmd is set on success/failure and isn't accessed | ||
238 | * by any other thread, anymore. */ | ||
239 | |||
226 | ret = wait_for_completion_interruptible_timeout(&wdata->state.ready, HZ); | 240 | ret = wait_for_completion_interruptible_timeout(&wdata->state.ready, HZ); |
227 | if (ret < 0) | 241 | if (ret < 0) |
228 | return -ERESTARTSYS; | 242 | return -ERESTARTSYS; |
229 | else if (ret == 0) | 243 | else if (ret == 0) |
230 | return -EIO; | 244 | return -EIO; |
245 | else if (wdata->state.cmd != WIIPROTO_REQ_NULL) | ||
246 | return -EIO; | ||
231 | else | 247 | else |
232 | return 0; | 248 | return 0; |
233 | } | 249 | } |
@@ -236,9 +252,12 @@ static inline int wiimote_cmd_wait_noint(struct wiimote_data *wdata) | |||
236 | { | 252 | { |
237 | unsigned long ret; | 253 | unsigned long ret; |
238 | 254 | ||
255 | /* no locking needed; see wiimote_cmd_wait() */ | ||
239 | ret = wait_for_completion_timeout(&wdata->state.ready, HZ); | 256 | ret = wait_for_completion_timeout(&wdata->state.ready, HZ); |
240 | if (!ret) | 257 | if (!ret) |
241 | return -EIO; | 258 | return -EIO; |
259 | else if (wdata->state.cmd != WIIPROTO_REQ_NULL) | ||
260 | return -EIO; | ||
242 | else | 261 | else |
243 | return 0; | 262 | return 0; |
244 | } | 263 | } |