mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-11 06:54:18 +00:00
libusb: retry configuration-descriptor retrieval
Some USB devices (e.g., webcams) fail to deliver their configuration descriptor early after power-up. Testing revealed that retrying the requests usually succeeds on second or third attempt. Fixes #4739
This commit is contained in:
parent
da673cfad7
commit
9de81369a7
@ -138,7 +138,7 @@ append config {
|
|||||||
<default-policy domain=""/>
|
<default-policy domain=""/>
|
||||||
</config>
|
</config>
|
||||||
<route>
|
<route>
|
||||||
<service name="Report"> <child name="acpi_report_rom"/> </service>
|
<service name="Report"> <child name="report_rom"/> </service>
|
||||||
<any-service> <parent/> <any-child /> </any-service>
|
<any-service> <parent/> <any-child /> </any-service>
|
||||||
</route>
|
</route>
|
||||||
</start>
|
</start>
|
||||||
|
@ -67,17 +67,9 @@ struct Usb_device
|
|||||||
Usb::Config_descriptor config_descriptor;
|
Usb::Config_descriptor config_descriptor;
|
||||||
char *raw_config_descriptor = nullptr;
|
char *raw_config_descriptor = nullptr;
|
||||||
|
|
||||||
Usb_device(Usb::Connection *usb)
|
bool _retrieve_raw_config_descriptor()
|
||||||
: usb_connection(usb)
|
|
||||||
{
|
{
|
||||||
Genode::log("libusb: waiting until device is plugged...");
|
Genode::log("libusb: retrieve configuration descriptor");
|
||||||
while (!usb_connection->plugged())
|
|
||||||
genode_env().ep().wait_and_dispatch_one_io_signal();
|
|
||||||
Genode::log("libusb: device is plugged");
|
|
||||||
|
|
||||||
usb_connection->config_descriptor(&device_descriptor, &config_descriptor);
|
|
||||||
|
|
||||||
raw_config_descriptor = (char*)malloc(config_descriptor.total_length);
|
|
||||||
|
|
||||||
Usb::Packet_descriptor p =
|
Usb::Packet_descriptor p =
|
||||||
usb_connection->alloc_packet(config_descriptor.total_length);
|
usb_connection->alloc_packet(config_descriptor.total_length);
|
||||||
@ -95,19 +87,39 @@ struct Usb_device
|
|||||||
|
|
||||||
p = usb_connection->source()->get_acked_packet();
|
p = usb_connection->source()->get_acked_packet();
|
||||||
|
|
||||||
if (!p.succeded)
|
bool ret = false;
|
||||||
|
if (!p.succeded) {
|
||||||
Genode::error(__PRETTY_FUNCTION__,
|
Genode::error(__PRETTY_FUNCTION__,
|
||||||
": could not read raw configuration descriptor");
|
": could not read raw configuration descriptor");
|
||||||
|
} else if (p.control.actual_size != config_descriptor.total_length) {
|
||||||
if (p.control.actual_size != config_descriptor.total_length)
|
|
||||||
Genode::error(__PRETTY_FUNCTION__,
|
Genode::error(__PRETTY_FUNCTION__,
|
||||||
": received configuration descriptor of unexpected size");
|
": received configuration descriptor of unexpected size");
|
||||||
|
} else {
|
||||||
char *packet_content = usb_connection->source()->packet_content(p);
|
char *packet_content = usb_connection->source()->packet_content(p);
|
||||||
Genode::memcpy(raw_config_descriptor, packet_content,
|
Genode::memcpy(raw_config_descriptor, packet_content,
|
||||||
config_descriptor.total_length);
|
config_descriptor.total_length);
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
usb_connection->source()->release_packet(p);
|
usb_connection->source()->release_packet(p);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Usb_device(Usb::Connection *usb)
|
||||||
|
: usb_connection(usb)
|
||||||
|
{
|
||||||
|
Genode::log("libusb: waiting until device is plugged...");
|
||||||
|
while (!usb_connection->plugged())
|
||||||
|
genode_env().ep().wait_and_dispatch_one_io_signal();
|
||||||
|
Genode::log("libusb: device is plugged");
|
||||||
|
|
||||||
|
usb_connection->config_descriptor(&device_descriptor, &config_descriptor);
|
||||||
|
|
||||||
|
raw_config_descriptor = (char*)malloc(config_descriptor.total_length);
|
||||||
|
|
||||||
|
for (unsigned attempt = 0; attempt < 10; ++attempt)
|
||||||
|
if (_retrieve_raw_config_descriptor())
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Usb_device()
|
~Usb_device()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user