HID: logitech-hidpp: Retry commands when device is busy
Handle the busy error coming from the device or receiver. The documentation says a busy error can be returned when: " Device (or receiver) cannot answer immediately to this request for any reason i.e: - already processing a request from the same or another SW - pipe full " Signed-off-by: Bastien Nocera <hadess@hadess.net> Link: https://lore.kernel.org/r/20230209154916.462158-1-hadess@hadess.net Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
This commit is contained in:
parent
a47a3b7af7
commit
586e8fede7
@ -283,6 +283,7 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp,
|
||||
struct hidpp_report *response)
|
||||
{
|
||||
int ret;
|
||||
int max_retries = 3;
|
||||
|
||||
mutex_lock(&hidpp->send_mutex);
|
||||
|
||||
@ -295,34 +296,39 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp,
|
||||
*/
|
||||
*response = *message;
|
||||
|
||||
ret = __hidpp_send_report(hidpp->hid_dev, message);
|
||||
for (; max_retries != 0; max_retries--) {
|
||||
ret = __hidpp_send_report(hidpp->hid_dev, message);
|
||||
|
||||
if (ret) {
|
||||
dbg_hid("__hidpp_send_report returned err: %d\n", ret);
|
||||
memset(response, 0, sizeof(struct hidpp_report));
|
||||
goto exit;
|
||||
}
|
||||
if (ret) {
|
||||
dbg_hid("__hidpp_send_report returned err: %d\n", ret);
|
||||
memset(response, 0, sizeof(struct hidpp_report));
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!wait_event_timeout(hidpp->wait, hidpp->answer_available,
|
||||
5*HZ)) {
|
||||
dbg_hid("%s:timeout waiting for response\n", __func__);
|
||||
memset(response, 0, sizeof(struct hidpp_report));
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
if (!wait_event_timeout(hidpp->wait, hidpp->answer_available,
|
||||
5*HZ)) {
|
||||
dbg_hid("%s:timeout waiting for response\n", __func__);
|
||||
memset(response, 0, sizeof(struct hidpp_report));
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (response->report_id == REPORT_ID_HIDPP_SHORT &&
|
||||
response->rap.sub_id == HIDPP_ERROR) {
|
||||
ret = response->rap.params[1];
|
||||
dbg_hid("%s:got hidpp error %02X\n", __func__, ret);
|
||||
goto exit;
|
||||
}
|
||||
if (response->report_id == REPORT_ID_HIDPP_SHORT &&
|
||||
response->rap.sub_id == HIDPP_ERROR) {
|
||||
ret = response->rap.params[1];
|
||||
dbg_hid("%s:got hidpp error %02X\n", __func__, ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((response->report_id == REPORT_ID_HIDPP_LONG ||
|
||||
response->report_id == REPORT_ID_HIDPP_VERY_LONG) &&
|
||||
response->fap.feature_index == HIDPP20_ERROR) {
|
||||
ret = response->fap.params[1];
|
||||
dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret);
|
||||
goto exit;
|
||||
if ((response->report_id == REPORT_ID_HIDPP_LONG ||
|
||||
response->report_id == REPORT_ID_HIDPP_VERY_LONG) &&
|
||||
response->fap.feature_index == HIDPP20_ERROR) {
|
||||
ret = response->fap.params[1];
|
||||
if (ret != HIDPP20_ERROR_BUSY) {
|
||||
dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret);
|
||||
goto exit;
|
||||
}
|
||||
dbg_hid("%s:got busy hidpp 2.0 error %02X, retrying\n", __func__, ret);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
|
Loading…
x
Reference in New Issue
Block a user