mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
usb: consider alternate setting in endpoint select
When constructing an Usb::Interface and implicitly corresponding Usb::Endpoint instances only select endpoints relevant for the given alternate setting. The libusb has to be changed to delegate the correct alternate setting to the constructor too. Fix genodelabs/genode#5394
This commit is contained in:
parent
97e638a2ac
commit
96d9f5d317
@ -58,7 +58,7 @@ struct Usb_device
|
|||||||
|
|
||||||
Usb_device &_device;
|
Usb_device &_device;
|
||||||
|
|
||||||
Interface(Usb_device &device, uint8_t idx);
|
Interface(Usb_device &device, uint8_t idx, uint8_t alt = 0);
|
||||||
|
|
||||||
void handle_events();
|
void handle_events();
|
||||||
};
|
};
|
||||||
@ -108,9 +108,10 @@ struct Usb_device
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Usb_device::Interface::Interface(Usb_device &device, uint8_t idx)
|
Usb_device::Interface::Interface(Usb_device &device, uint8_t idx, uint8_t alt)
|
||||||
:
|
:
|
||||||
Usb::Interface(device._device, Usb::Interface::Index{idx, 0}, (1UL << 20)),
|
Usb::Interface(device._device, Usb::Interface::Index{idx, alt},
|
||||||
|
(1UL << 20)),
|
||||||
Registry<Usb_device::Interface>::Element(device._interfaces, *this),
|
Registry<Usb_device::Interface>::Element(device._interfaces, *this),
|
||||||
_device(device)
|
_device(device)
|
||||||
{
|
{
|
||||||
@ -461,11 +462,21 @@ static int genode_set_interface_altsetting(struct libusb_device_handle* dev_hand
|
|||||||
altsetting < 0 || altsetting > 0xff)
|
altsetting < 0 || altsetting > 0xff)
|
||||||
return LIBUSB_ERROR_INVALID_PARAM;
|
return LIBUSB_ERROR_INVALID_PARAM;
|
||||||
|
|
||||||
|
/* remove already claimed interface with old setting */
|
||||||
|
device()._interfaces.for_each([&] (Usb_device::Interface &iface) {
|
||||||
|
if (iface.index().number == interface_number)
|
||||||
|
destroy(device()._alloc, &iface); });
|
||||||
|
|
||||||
Usb_device::Urb urb(nullptr, 0, device()._device, P::Request::SET_INTERFACE,
|
Usb_device::Urb urb(nullptr, 0, device()._device, P::Request::SET_INTERFACE,
|
||||||
Rt::value(P::Recipient::IFACE, P::Type::STANDARD,
|
Rt::value(P::Recipient::IFACE, P::Type::STANDARD,
|
||||||
P::Direction::OUT),
|
P::Direction::OUT),
|
||||||
(uint8_t)altsetting, (uint8_t)interface_number, 0);
|
(uint8_t)altsetting, (uint8_t)interface_number, 0);
|
||||||
device()._wait_for_urb(urb);
|
device()._wait_for_urb(urb);
|
||||||
|
|
||||||
|
/* claim interface */
|
||||||
|
new (device()._alloc)
|
||||||
|
Usb_device::Interface(device(), (uint8_t) interface_number,
|
||||||
|
(uint8_t) altsetting);
|
||||||
return LIBUSB_SUCCESS;
|
return LIBUSB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,6 +671,8 @@ inline Usb::Interface::Interface(Device &device, Index idx, size_t buffer_size)
|
|||||||
device._for_each_iface([&] (Xml_node node) {
|
device._for_each_iface([&] (Xml_node node) {
|
||||||
if (node.attribute_value<uint16_t>("number", INVALID) != idx.number)
|
if (node.attribute_value<uint16_t>("number", INVALID) != idx.number)
|
||||||
return;
|
return;
|
||||||
|
if (node.attribute_value<uint16_t>("alt_setting", INVALID) != idx.alt_setting)
|
||||||
|
return;
|
||||||
node.for_each_sub_node("endpoint", [&] (Xml_node node) {
|
node.for_each_sub_node("endpoint", [&] (Xml_node node) {
|
||||||
Endpoint ep { node.attribute_value<uint8_t>("address", 0),
|
Endpoint ep { node.attribute_value<uint8_t>("address", 0),
|
||||||
node.attribute_value<uint8_t>("attributes", 0) };
|
node.attribute_value<uint8_t>("attributes", 0) };
|
||||||
|
Loading…
Reference in New Issue
Block a user