diff options
author | Peter Wu <peter@lekensteyn.nl> | 2014-03-19 23:43:09 +0100 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2014-12-12 17:44:08 +0100 |
commit | 072040555cbd9f8e9b0502bad0f9ddd237349130 (patch) | |
tree | 8af58b6bcf8f0614f466c950a757808c10c8dc15 /hw | |
parent | 258a8648cc6b5fe4f7d9ac046de1c69313214f04 (diff) | |
download | qemu-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.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); } |