usb_hid: Fix MaxReportSize computation

While calculating buffer size for IN reports, only "Input" report type
should been taken in account. Complex HID devices, such as "Gaming"
keyboards and mice, often have "Feature"-reports declared (with size way
bigger than "typical" kbd IN report) for vendor-specific device
configurations.

But "Feature"-reports are sent over control channel only and can't
appear on interrupt channel.

Should fix #14919, #17937, #17699

Change-Id: I4b9eb51938ca4aba2bc34247d00ae164eb2c19fc
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5771
Reviewed-by: Jérôme Duval <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
Zelenoviy
2022-11-02 02:21:02 +00:00
committed by waddlesplash
parent b71020b095
commit 4f18dc0496
4 changed files with 15 additions and 3 deletions
@@ -430,6 +430,13 @@ HIDParser::ReportAt(uint8 type, uint8 index)
size_t
HIDParser::MaxReportSize()
{
return MaxReportSize(HID_REPORT_TYPE_ANY);
}
size_t
HIDParser::MaxReportSize(uint8 type)
{
size_t maxSize = 0;
for (int32 i = 0; i < fReports.Count(); i++) {
@@ -437,6 +444,9 @@ HIDParser::MaxReportSize()
if (report == NULL)
continue;
if (type != HID_REPORT_TYPE_ANY && report->Type() != type)
continue;
if (report->ReportSize() > maxSize)
maxSize = report->ReportSize();
}
@@ -30,6 +30,7 @@ public:
uint8 CountReports(uint8 type);
HIDReport * ReportAt(uint8 type, uint8 index);
size_t MaxReportSize();
size_t MaxReportSize(uint8 type);
HIDCollection * RootCollection() { return fRootCollection; };
@@ -110,7 +110,8 @@ KeyboardProtocolHandler::KeyboardProtocolHandler(HIDReport &inputReport,
#ifdef USB_KDL
sDebugKeyboardPipe = fInputReport.Device()->InterruptPipe();
#endif
sDebugKeyboardReportSize = fInputReport.Parser()->MaxReportSize();
sDebugKeyboardReportSize =
fInputReport.Parser()->MaxReportSize(HID_REPORT_TYPE_INPUT);
if (outputReport != NULL)
sDebugKeyboardFound = true;
}
@@ -794,7 +795,7 @@ KeyboardProtocolHandler::_ReadReport(bigtime_t timeout, uint32 *cookie)
= fInputReport.Device()->InterruptPipe();
#endif
sDebugKeyboardReportSize
= fInputReport.Parser()->MaxReportSize();
= fInputReport.Parser()->MaxReportSize(HID_REPORT_TYPE_INPUT);
#endif
char letter = current[i] - 4 + 'a';
@@ -181,7 +181,7 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config,
return;
}
fTransferBufferSize = fParser.MaxReportSize();
fTransferBufferSize = fParser.MaxReportSize(HID_REPORT_TYPE_INPUT);
if (fTransferBufferSize == 0) {
TRACE_ALWAYS("report claims a report size of 0\n");
return;