Get the HID descriptor from the already retrieved configuration info instead of
always calling the device and requesting it. If no HID descriptor is found in the configuration we fall back to retrieving it manually and if that fails we fall back to a dummy report descriptor length. In the most usual case this will save one unnecessary USB control request. Incidentally this also fixes the absolute pointing device under VirtualBox. VBox stalled the retrieval of the HID descriptor. That alone wasn't so problematic as in this case we just fell back to the dummy report descriptor length which would've been large enough. But VBox also times out the next request after the stall, which in this case was the retrieval of the report descriptor, hence no HIDDevice could be created. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42019 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
8a480e5d69
commit
7802e2dd2c
@ -60,31 +60,55 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!hasFixedDescriptor) {
|
if (!hasFixedDescriptor) {
|
||||||
// conforming device, read HID and report descriptors
|
// Conforming device, find the HID descriptor and get the report
|
||||||
descriptorLength = sizeof(usb_hid_descriptor);
|
// descriptor from the device.
|
||||||
usb_hid_descriptor *hidDescriptor
|
usb_hid_descriptor *hidDescriptor = NULL;
|
||||||
= (usb_hid_descriptor *)malloc(descriptorLength);
|
|
||||||
if (hidDescriptor == NULL) {
|
const usb_interface_info *interfaceInfo
|
||||||
TRACE_ALWAYS("failed to allocate buffer for hid descriptor\n");
|
= config->interface[interfaceIndex].active;
|
||||||
fStatus = B_NO_MEMORY;
|
for (size_t i = 0; i < interfaceInfo->generic_count; i++) {
|
||||||
return;
|
const usb_generic_descriptor &generic
|
||||||
|
= interfaceInfo->generic[i]->generic;
|
||||||
|
if (generic.descriptor_type == B_USB_HID_DESCRIPTOR_HID) {
|
||||||
|
hidDescriptor = (usb_hid_descriptor *)&generic;
|
||||||
|
descriptorLength
|
||||||
|
= hidDescriptor->descriptor_info[0].descriptor_length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t result = gUSBModule->send_request(device,
|
if (hidDescriptor == NULL) {
|
||||||
USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_STANDARD,
|
TRACE_ALWAYS("didn't find a HID descriptor in the configuration, "
|
||||||
USB_REQUEST_GET_DESCRIPTOR,
|
"trying to retrieve manually\n");
|
||||||
B_USB_HID_DESCRIPTOR_HID << 8, interfaceIndex, descriptorLength,
|
|
||||||
hidDescriptor, &descriptorLength);
|
|
||||||
|
|
||||||
TRACE("get hid descriptor: result: 0x%08lx; length: %lu\n", result,
|
descriptorLength = sizeof(usb_hid_descriptor);
|
||||||
descriptorLength);
|
hidDescriptor = (usb_hid_descriptor *)malloc(descriptorLength);
|
||||||
if (result == B_OK) {
|
if (hidDescriptor == NULL) {
|
||||||
descriptorLength
|
TRACE_ALWAYS("failed to allocate buffer for hid descriptor\n");
|
||||||
= hidDescriptor->descriptor_info[0].descriptor_length;
|
fStatus = B_NO_MEMORY;
|
||||||
} else
|
return;
|
||||||
descriptorLength = 256; /* XXX */
|
}
|
||||||
|
|
||||||
free(hidDescriptor);
|
status_t result = gUSBModule->send_request(device,
|
||||||
|
USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_STANDARD,
|
||||||
|
USB_REQUEST_GET_DESCRIPTOR,
|
||||||
|
B_USB_HID_DESCRIPTOR_HID << 8, interfaceIndex, descriptorLength,
|
||||||
|
hidDescriptor, &descriptorLength);
|
||||||
|
|
||||||
|
TRACE("get hid descriptor: result: 0x%08lx; length: %lu\n", result,
|
||||||
|
descriptorLength);
|
||||||
|
if (result == B_OK) {
|
||||||
|
descriptorLength
|
||||||
|
= hidDescriptor->descriptor_info[0].descriptor_length;
|
||||||
|
} else {
|
||||||
|
descriptorLength = 256; /* XXX */
|
||||||
|
TRACE_ALWAYS("failed to get HID descriptor, trying with a "
|
||||||
|
"fallback report descriptor length of %lu\n",
|
||||||
|
descriptorLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(hidDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
reportDescriptor = (uint8 *)malloc(descriptorLength);
|
reportDescriptor = (uint8 *)malloc(descriptorLength);
|
||||||
if (reportDescriptor == NULL) {
|
if (reportDescriptor == NULL) {
|
||||||
@ -93,7 +117,7 @@ HIDDevice::HIDDevice(usb_device device, const usb_configuration_info *config,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = gUSBModule->send_request(device,
|
status_t result = gUSBModule->send_request(device,
|
||||||
USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_STANDARD,
|
USB_REQTYPE_INTERFACE_IN | USB_REQTYPE_STANDARD,
|
||||||
USB_REQUEST_GET_DESCRIPTOR,
|
USB_REQUEST_GET_DESCRIPTOR,
|
||||||
B_USB_HID_DESCRIPTOR_REPORT << 8, interfaceIndex, descriptorLength,
|
B_USB_HID_DESCRIPTOR_REPORT << 8, interfaceIndex, descriptorLength,
|
||||||
|
Loading…
Reference in New Issue
Block a user