diff options
Diffstat (limited to 'drivers/hid/hid-wiimote.c')
-rw-r--r-- | drivers/hid/hid-wiimote.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c index 0a5e458820b2..59a08933c73c 100644 --- a/drivers/hid/hid-wiimote.c +++ b/drivers/hid/hid-wiimote.c | |||
@@ -39,6 +39,9 @@ struct wiimote_state { | |||
39 | struct completion ready; | 39 | struct completion ready; |
40 | int cmd; | 40 | int cmd; |
41 | __u32 opt; | 41 | __u32 opt; |
42 | |||
43 | /* results of synchronous requests */ | ||
44 | __u8 cmd_err; | ||
42 | }; | 45 | }; |
43 | 46 | ||
44 | struct wiimote_data { | 47 | struct wiimote_data { |
@@ -394,6 +397,25 @@ static void wiiproto_req_wmem(struct wiimote_data *wdata, bool eeprom, | |||
394 | wiimote_queue(wdata, cmd, sizeof(cmd)); | 397 | wiimote_queue(wdata, cmd, sizeof(cmd)); |
395 | } | 398 | } |
396 | 399 | ||
400 | /* requries the cmd-mutex to be held */ | ||
401 | static int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset, | ||
402 | const __u8 *wmem, __u8 size) | ||
403 | { | ||
404 | unsigned long flags; | ||
405 | int ret; | ||
406 | |||
407 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
408 | wiimote_cmd_set(wdata, WIIPROTO_REQ_WMEM, 0); | ||
409 | wiiproto_req_wreg(wdata, offset, wmem, size); | ||
410 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
411 | |||
412 | ret = wiimote_cmd_wait(wdata); | ||
413 | if (!ret && wdata->state.cmd_err) | ||
414 | ret = -EIO; | ||
415 | |||
416 | return ret; | ||
417 | } | ||
418 | |||
397 | static enum led_brightness wiimote_leds_get(struct led_classdev *led_dev) | 419 | static enum led_brightness wiimote_leds_get(struct led_classdev *led_dev) |
398 | { | 420 | { |
399 | struct wiimote_data *wdata; | 421 | struct wiimote_data *wdata; |
@@ -635,9 +657,13 @@ static void handler_return(struct wiimote_data *wdata, const __u8 *payload) | |||
635 | 657 | ||
636 | handler_keys(wdata, payload); | 658 | handler_keys(wdata, payload); |
637 | 659 | ||
638 | if (err) | 660 | if (wiimote_cmd_pending(wdata, cmd, 0)) { |
661 | wdata->state.cmd_err = err; | ||
662 | wiimote_cmd_complete(wdata); | ||
663 | } else if (err) { | ||
639 | hid_warn(wdata->hdev, "Remote error %hhu on req %hhu\n", err, | 664 | hid_warn(wdata->hdev, "Remote error %hhu on req %hhu\n", err, |
640 | cmd); | 665 | cmd); |
666 | } | ||
641 | } | 667 | } |
642 | 668 | ||
643 | static void handler_drm_KA(struct wiimote_data *wdata, const __u8 *payload) | 669 | static void handler_drm_KA(struct wiimote_data *wdata, const __u8 *payload) |