From a4a17543cee0f422b6348020d170d887f05e97fc Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Mon, 24 Mar 2014 00:00:05 +0100 Subject: unifying: implement IRoot completely Do not treat IRoot special in hidpp_process_device_hidpp20, but implement it as a generic feature using hidpp20_feature_call. This makes it easier to re-use the error reporting stuff. Signed-off-by: Peter Wu --- hw/usb/hid-logitech-dj.c | 12 ------------ hw/usb/hid-logitech-hidpp20.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 34 insertions(+), 14 deletions(-) (limited to 'hw') diff --git a/hw/usb/hid-logitech-dj.c b/hw/usb/hid-logitech-dj.c index 6de5fa4ba1..51be0e2410 100644 --- a/hw/usb/hid-logitech-dj.c +++ b/hw/usb/hid-logitech-dj.c @@ -399,20 +399,8 @@ static void hidpp_process_device_hidpp20(USBLtunifyState *s, HidppMsg *msg) { LHidDevice *hd = &s->devices[msg->device_index - 1]; Hidpp20Msg *func = (Hidpp20Msg *) msg; - uint8_t fn = func->func >> 4; int r; - if (func->feat_index == 0) { /* IRoot */ - if (fn == 1) { /* GetProtocolVersion */ - func->params_s[0] = (uint8_t) (hd->info.protocol_version >> 8); - func->params_s[1] = (uint8_t) hd->info.protocol_version; - hidpp_queue_output_report(s, msg); - } else { - hidpp20_queue_error(s, func, HIDPP20_ERR_CODE_INVALID_FUNCTION_ID); - } - return; - } - r = hidpp20_feature_call(hd, func); /* note: if r == 0, then the function is void and there is no output */ if (r > 0) { diff --git a/hw/usb/hid-logitech-hidpp20.c b/hw/usb/hid-logitech-hidpp20.c index be1e02df53..95393050a5 100644 --- a/hw/usb/hid-logitech-hidpp20.c +++ b/hw/usb/hid-logitech-hidpp20.c @@ -48,6 +48,34 @@ struct HidppFeature { #define HIDPP20_FEATURE(name) \ int name(LHidDevice *hd, Hidpp20Msg *msg, uint8_t fn, uint8_t *params) +static HIDPP20_FEATURE(feat_iroot) +{ + uint16_t feature_id; + unsigned i; + const HidppFeature *feat; + + switch (fn) { + case 0: /* featureIndex, featureType = GetFeature(featureID) */ + feature_id = (params[0] << 8) | params[1]; + params[0] = params[1] = 0; + for (i = 0; i < hd->info.features_count; i++) { + feat = &hd->info.features[i]; + if (feat->id == feature_id) { + params[0] = i + 1; + params[1] = feat->type; + } + } + return 2; + case 1: /* ping = GetFeature(pingData) or version = GetProtocolVersion() */ + params[0] = hd->info.protocol_version >> 8; + params[1] = (uint8_t) hd->info.protocol_version; + // params[2] is not changed, that's the pingData + return 3; + default: + return -HIDPP20_ERR_CODE_INVALID_FUNCTION_ID; + } +} + static HIDPP20_FEATURE(feat_featureset) { const HidppFeature *feat; @@ -96,8 +124,12 @@ int hidpp20_feature_call(LHidDevice *hd, Hidpp20Msg *func) assert(hd->info.features != NULL); - feat = &hd->info.features[func->feat_index - 1]; - r = feat->callback(hd, func, fn, func->params); + if (func->feat_index == 0) { /* IRoot (dual HID++ 1.0 and HID++ 2.0) */ + r = feat_iroot(hd, func, fn, func->params); + } else { /* other features */ + feat = &hd->info.features[func->feat_index - 1]; + r = feat->callback(hd, func, fn, func->params); + } if (r > 0) { // r are the parameters that must be kept, the others are cleared. assert(r <= sizeof(func->params)); -- cgit v1.2.1