aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-wiimote.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-wiimote.h')
-rw-r--r--drivers/hid/hid-wiimote.h19
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 */
199static 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
198static inline int wiimote_cmd_acquire(struct wiimote_data *wdata) 208static 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}