summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-03-19 23:43:09 +0100
committerPeter Wu <peter@lekensteyn.nl>2014-12-12 17:44:08 +0100
commit072040555cbd9f8e9b0502bad0f9ddd237349130 (patch)
tree8af58b6bcf8f0614f466c950a757808c10c8dc15 /hw
parent258a8648cc6b5fe4f7d9ac046de1c69313214f04 (diff)
downloadqemu-072040555cbd9f8e9b0502bad0f9ddd237349130.tar.gz
unifying: start implementing device report processing
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'hw')
-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);
}