diff --git a/src/add-ons/kernel/drivers/input/usb_hid/HIDParser.cpp b/src/add-ons/kernel/drivers/input/usb_hid/HIDParser.cpp index 26e27a1ae4..0d62d35f36 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/HIDParser.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/HIDParser.cpp @@ -448,34 +448,34 @@ HIDParser::MaxReportSize() void HIDParser::SetReport(status_t status, uint8 *report, size_t length) { - if (status != B_OK) { - // in case of error we need to notify all input reports, as we don't - // know who has waiting listeners. - for (uint32 i = 0; i < fReportCount; i++) { - if (fReports[i] == NULL - || fReports[i]->Type() != HID_REPORT_TYPE_INPUT) - continue; + if (status != B_OK || length == 0) { + if (status == B_OK) + status = B_ERROR; - fReports[i]->SetReport(status, NULL, 0); - } - - return; + report = NULL; + length = 0; } - HIDReport *target = NULL; - if (fUsesReportIDs) { - target = FindReport(HID_REPORT_TYPE_INPUT, report[0]); + uint8 targetID = 0; + if (fUsesReportIDs && status == B_OK) { + targetID = report[0]; report++; length--; - } else - target = FindReport(HID_REPORT_TYPE_INPUT, 0); - - if (target == NULL) { - TRACE_ALWAYS("got report buffer but found no report to handle it\n"); - return; } - target->SetReport(status, report, length); + // We need to notify all input reports, as we don't know who has waiting + // listeners. Anyone other than the target report also waiting for a + // transfer to happen needs to reschedule one now. + for (uint32 i = 0; i < fReportCount; i++) { + if (fReports[i] == NULL + || fReports[i]->Type() != HID_REPORT_TYPE_INPUT) + continue; + + if (fReports[i]->ID() == targetID) + fReports[i]->SetReport(status, report, length); + else + fReports[i]->SetReport(B_INTERRUPTED, NULL, 0); + } } diff --git a/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.cpp b/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.cpp index c614854534..f7971e637f 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/KeyboardDevice.cpp @@ -334,8 +334,10 @@ KeyboardDevice::_ReadReport(bigtime_t timeout) return B_ERROR; } - if (result != B_TIMED_OUT) { - // we expect timeouts as we do repeat key handling this way + if (result != B_TIMED_OUT && result != B_INTERRUPTED) { + // we expect timeouts as we do repeat key handling this way, + // interrupts happen when other reports come in on the same + // endpoint TRACE_ALWAYS("error waiting for report: %s\n", strerror(result)); } diff --git a/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.cpp b/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.cpp index aa01c5f42b..0efbff3f35 100644 --- a/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.cpp +++ b/src/add-ons/kernel/drivers/input/usb_hid/MouseDevice.cpp @@ -116,7 +116,12 @@ MouseDevice::_ReadReport() return B_ERROR; } - TRACE_ALWAYS("error waiting for report: %s\n", strerror(result)); + if (result != B_INTERRUPTED) { + // interrupts happen when other reports come in on the same + // input as ours + TRACE_ALWAYS("error waiting for report: %s\n", strerror(result)); + } + // signal that we simply want to try again return B_OK; }