|
@@ -39,6 +39,9 @@ struct wiimote_state {
|
|
|
struct completion ready;
|
|
|
int cmd;
|
|
|
__u32 opt;
|
|
|
+
|
|
|
+ /* results of synchronous requests */
|
|
|
+ __u8 cmd_err;
|
|
|
};
|
|
|
|
|
|
struct wiimote_data {
|
|
@@ -394,6 +397,25 @@ static void wiiproto_req_wmem(struct wiimote_data *wdata, bool eeprom,
|
|
|
wiimote_queue(wdata, cmd, sizeof(cmd));
|
|
|
}
|
|
|
|
|
|
+/* requries the cmd-mutex to be held */
|
|
|
+static int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
|
|
|
+ const __u8 *wmem, __u8 size)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&wdata->state.lock, flags);
|
|
|
+ wiimote_cmd_set(wdata, WIIPROTO_REQ_WMEM, 0);
|
|
|
+ wiiproto_req_wreg(wdata, offset, wmem, size);
|
|
|
+ spin_unlock_irqrestore(&wdata->state.lock, flags);
|
|
|
+
|
|
|
+ ret = wiimote_cmd_wait(wdata);
|
|
|
+ if (!ret && wdata->state.cmd_err)
|
|
|
+ ret = -EIO;
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static enum led_brightness wiimote_leds_get(struct led_classdev *led_dev)
|
|
|
{
|
|
|
struct wiimote_data *wdata;
|
|
@@ -635,9 +657,13 @@ static void handler_return(struct wiimote_data *wdata, const __u8 *payload)
|
|
|
|
|
|
handler_keys(wdata, payload);
|
|
|
|
|
|
- if (err)
|
|
|
+ if (wiimote_cmd_pending(wdata, cmd, 0)) {
|
|
|
+ wdata->state.cmd_err = err;
|
|
|
+ wiimote_cmd_complete(wdata);
|
|
|
+ } else if (err) {
|
|
|
hid_warn(wdata->hdev, "Remote error %hhu on req %hhu\n", err,
|
|
|
cmd);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void handler_drm_KA(struct wiimote_data *wdata, const __u8 *payload)
|