summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-03-19 23:43:09 +0100
committerPeter Wu <peter@lekensteyn.nl>2014-03-19 23:43:09 +0100
commit28702c7fa5e93e5597e08014edc95b13df414936 (patch)
tree2d4c910cd9d96da654bcef01e6b042b61dcbce87
parent0fe6150d9bd5a68f6f2e6d5df3109d60af971995 (diff)
downloadqemu-28702c7fa5e93e5597e08014edc95b13df414936.tar.gz
unifying: start implementing device report processing
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
-rw-r--r--hw/usb/hid-logitech-dj.c43
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);
}