aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-12-15 19:50:14 -0500
committerJiri Kosina <jkosina@suse.cz>2014-12-19 05:44:11 -0500
commitf677bb150c2f7b96ebcd377cd722e9d2649e9400 (patch)
tree7887f94189f6ea7d55a879564f889e3983674a13
parentb1ac9487c824a212f3b5bb80df5ac578243b0e21 (diff)
HID: logitech-hidpp: detect HID++ 2.0 errors too
Devices speaking HID++ 2.0 report a different error code (0xff). Detect these errors too to avoid 5 second delays when the device reports an error. Caught by... well, a bug in the QEMU emulation of this receiver. Renamed fap to rap for HID++ 1.0 errors because it is more logical, it has no functional difference. Signed-off-by: Peter Wu <peter@lekensteyn.nl> Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-logitech-hidpp.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 7efbd8bd49c1..cf5795552bcc 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -105,6 +105,7 @@ struct hidpp_device {
105}; 105};
106 106
107 107
108/* HID++ 1.0 error codes */
108#define HIDPP_ERROR 0x8f 109#define HIDPP_ERROR 0x8f
109#define HIDPP_ERROR_SUCCESS 0x00 110#define HIDPP_ERROR_SUCCESS 0x00
110#define HIDPP_ERROR_INVALID_SUBID 0x01 111#define HIDPP_ERROR_INVALID_SUBID 0x01
@@ -119,6 +120,8 @@ struct hidpp_device {
119#define HIDPP_ERROR_REQUEST_UNAVAILABLE 0x0a 120#define HIDPP_ERROR_REQUEST_UNAVAILABLE 0x0a
120#define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b 121#define HIDPP_ERROR_INVALID_PARAM_VALUE 0x0b
121#define HIDPP_ERROR_WRONG_PIN_CODE 0x0c 122#define HIDPP_ERROR_WRONG_PIN_CODE 0x0c
123/* HID++ 2.0 error codes */
124#define HIDPP20_ERROR 0xff
122 125
123static void hidpp_connect_event(struct hidpp_device *hidpp_dev); 126static void hidpp_connect_event(struct hidpp_device *hidpp_dev);
124 127
@@ -192,9 +195,16 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp,
192 } 195 }
193 196
194 if (response->report_id == REPORT_ID_HIDPP_SHORT && 197 if (response->report_id == REPORT_ID_HIDPP_SHORT &&
195 response->fap.feature_index == HIDPP_ERROR) { 198 response->rap.sub_id == HIDPP_ERROR) {
199 ret = response->rap.params[1];
200 dbg_hid("%s:got hidpp error %02X\n", __func__, ret);
201 goto exit;
202 }
203
204 if (response->report_id == REPORT_ID_HIDPP_LONG &&
205 response->fap.feature_index == HIDPP20_ERROR) {
196 ret = response->fap.params[1]; 206 ret = response->fap.params[1];
197 dbg_hid("__hidpp_send_report got hidpp error %02X\n", ret); 207 dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret);
198 goto exit; 208 goto exit;
199 } 209 }
200 210
@@ -271,7 +281,8 @@ static inline bool hidpp_match_answer(struct hidpp_report *question,
271static inline bool hidpp_match_error(struct hidpp_report *question, 281static inline bool hidpp_match_error(struct hidpp_report *question,
272 struct hidpp_report *answer) 282 struct hidpp_report *answer)
273{ 283{
274 return (answer->fap.feature_index == HIDPP_ERROR) && 284 return ((answer->rap.sub_id == HIDPP_ERROR) ||
285 (answer->fap.feature_index == HIDPP20_ERROR)) &&
275 (answer->fap.funcindex_clientid == question->fap.feature_index) && 286 (answer->fap.funcindex_clientid == question->fap.feature_index) &&
276 (answer->fap.params[0] == question->fap.funcindex_clientid); 287 (answer->fap.params[0] == question->fap.funcindex_clientid);
277} 288}