diff options
author | Peter Wu <peter@lekensteyn.nl> | 2014-03-19 23:43:09 +0100 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2014-03-19 23:43:09 +0100 |
commit | 28702c7fa5e93e5597e08014edc95b13df414936 (patch) | |
tree | 2d4c910cd9d96da654bcef01e6b042b61dcbce87 /hw/usb/hid-logitech-dj.c | |
parent | 0fe6150d9bd5a68f6f2e6d5df3109d60af971995 (diff) | |
download | qemu-28702c7fa5e93e5597e08014edc95b13df414936.tar.gz |
unifying: start implementing device report processing
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'hw/usb/hid-logitech-dj.c')
-rw-r--r-- | hw/usb/hid-logitech-dj.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/hw/usb/hid-logitech-dj.c b/hw/usb/hid-logitech-dj.c index 883830a841..dc3d9c171d 100644 --- a/hw/usb/hid-logitech-dj.c +++ b/hw/usb/hid-logitech-dj.c @@ -302,14 +302,53 @@ static void hidpp_process_receiver_report(USBLtunifyState *s, HidppMsg *msg) } } +/* called for HID++ reports targeted at devices */ +static void hidpp_process_device_hidpp10(USBLtunifyState *s, HidppMsg *msg) +{ + LHidDevice *hd = &s->devices[msg->device_index - 1]; + HidppMsgLong *ml = &msg->hidpp_l; + unsigned req = (ml->report_id << 16) | (ml->sub_id << 8) | ml->address; + uint8_t *parms = ml->value; /* NOTE: drops address */ + + switch (req) { + case GET_REG(0x00): /* Enable HID++ notifs */ + parms[0] = (uint8_t) hd->reporting_flags; + parms[1] = 0; + parms[2] = (uint8_t) (hd->reporting_flags >> 8); + hidpp_queue_output_report(s, msg); + break; + case SET_REG(0x00): /* Enable HID++ notifs */ + hd->reporting_flags = (parms[2] << 8) | parms[0]; + hd->reporting_flags &= REPORTING_FLAG_DEV_MASK; + memset(parms, 0, 3); + hidpp_queue_output_report(s, msg); + break; + default: + /* unknown request, return error */ + switch (req & ~0xFF) { + case SET_REG(0): + case GET_REG(0): + case SET_LONG_REG(0): + case GET_LONG_REG(0): + /* register request unsatisfied */ + hidpp_queue_error(s, msg, HIDPP_ERR_INVALID_ADDRESS); + break; + default: + /* invalid report ID and command SubID combination */ + hidpp_queue_error(s, msg, HIDPP_ERR_INVALID_SUBID); + } + } +} + static void hidpp_process_input_report(USBLtunifyState *s, HidppMsg msg) { /* receiver reports are processed earlier, elsewhere */ assert(msg.device_index != 0xFF); if (hidpp_device_available(s, msg.device_index)) { - /* TODO: implement for devices */ - hidpp_queue_error(s, &msg, HIDPP_ERR_REQUEST_UNAVAILABLE); + if (msg.report_id == HIDPP_SHORT || msg.report_id == HIDPP_LONG) { + hidpp_process_device_hidpp10(s, &msg); + } } else { hidpp_queue_error(s, &msg, HIDPP_ERR_RESOURCE_ERROR); } |