diff --git a/repos/dde_linux/src/drivers/usb/raw/raw.cc b/repos/dde_linux/src/drivers/usb/raw/raw.cc index f8ea31bdf7..efa86bf29b 100644 --- a/repos/dde_linux/src/drivers/usb/raw/raw.cc +++ b/repos/dde_linux/src/drivers/usb/raw/raw.cc @@ -441,13 +441,12 @@ class Usb::Worker : public Genode::Weak_object { usb_host_config *config = _device->udev->actconfig; - if (!config) - return; - - for (unsigned i = 0; i < config->desc.bNumInterfaces; i++) { - if (usb_interface_claimed(config->interface[i])) { - error("There are interfaces claimed, won't set configuration"); - return; + if (config) { + for (unsigned i = 0; i < config->desc.bNumInterfaces; i++) { + if (usb_interface_claimed(config->interface[i])) { + error("There are interfaces claimed, won't set configuration"); + return; + } } } @@ -816,6 +815,29 @@ class Usb::Session_component : public Session_rpc_object, interface_descr->active = true; } + bool interface_extra(unsigned index, unsigned alt_setting, + Interface_extra *interface_data) + { + if (!_device) + throw Device_not_found(); + + usb_interface *iface = _device->interface(index); + if (!iface) + throw Interface_not_found(); + + Genode::uint8_t length = iface->altsetting[alt_setting].extralen; + if (length == 0) return false; + + if (length > sizeof(Interface_extra::data)) + length = sizeof(Interface_extra::data); + + Genode::memcpy(interface_data->data, iface->altsetting[alt_setting].extra, + length); + + interface_data->length = length; + return true; + } + void endpoint_descriptor(unsigned interface_num, unsigned alt_setting, unsigned endpoint_num, diff --git a/repos/dde_linux/src/drivers/usb_host/lx_emul.h b/repos/dde_linux/src/drivers/usb_host/lx_emul.h index 7fc072de65..b022091edb 100644 --- a/repos/dde_linux/src/drivers/usb_host/lx_emul.h +++ b/repos/dde_linux/src/drivers/usb_host/lx_emul.h @@ -1742,11 +1742,14 @@ struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np, const cha static inline u32 __raw_readl(const volatile void __iomem *addr) { - return *(const volatile u32 __force *) addr; + u32 val = *(const volatile u32 __force *) addr; + iormb(); + return val; } static inline void __raw_writel(u32 b, volatile void __iomem *addr) { + iowmb(); *(volatile u32 __force *) addr = b; } diff --git a/repos/dde_linux/src/drivers/usb_host/raw.cc b/repos/dde_linux/src/drivers/usb_host/raw.cc index 95cd04a113..4aa4b213d6 100644 --- a/repos/dde_linux/src/drivers/usb_host/raw.cc +++ b/repos/dde_linux/src/drivers/usb_host/raw.cc @@ -452,13 +452,12 @@ class Usb::Worker : public Genode::Weak_object { usb_host_config *config = _device->udev->actconfig; - if (!config) - return; - - for (unsigned i = 0; i < config->desc.bNumInterfaces; i++) { - if (usb_interface_claimed(config->interface[i])) { - error("There are interfaces claimed, won't set configuration"); - return; + if (config) { + for (unsigned i = 0; i < config->desc.bNumInterfaces; i++) { + if (usb_interface_claimed(config->interface[i])) { + error("There are interfaces claimed, won't set configuration"); + return; + } } } @@ -836,6 +835,29 @@ class Usb::Session_component : public Session_rpc_object, interface_descr->active = true; } + bool interface_extra(unsigned index, unsigned alt_setting, + Interface_extra *interface_data) + { + if (!_device) + throw Device_not_found(); + + usb_interface *iface = _device->interface(index); + if (!iface) + throw Interface_not_found(); + + Genode::uint8_t length = iface->altsetting[alt_setting].extralen; + if (length == 0) return false; + + if (length > sizeof(Interface_extra::data)) + length = sizeof(Interface_extra::data); + + Genode::memcpy(interface_data->data, iface->altsetting[alt_setting].extra, + length); + + interface_data->length = length; + return true; + } + void endpoint_descriptor(unsigned interface_num, unsigned alt_setting, unsigned endpoint_num, diff --git a/repos/os/include/usb/types.h b/repos/os/include/usb/types.h index 3ca90c5a9c..ab17e20fab 100644 --- a/repos/os/include/usb/types.h +++ b/repos/os/include/usb/types.h @@ -22,6 +22,7 @@ namespace Usb { struct Interface_descriptor; struct Endpoint_descriptor; struct String; + struct Interface_extra; } namespace Usb { @@ -193,9 +194,19 @@ struct Usb::Interface_descriptor * Genode extensions (POD only) */ bool active = false; - } __attribute__((packed)); + +/** + * Vendor specific data + */ +struct Usb::Interface_extra +{ + Genode::uint8_t length; + Genode::uint8_t data[32]; +}; + + /** * USB hardware endpoint descriptor */ diff --git a/repos/os/include/usb_session/client.h b/repos/os/include/usb_session/client.h index 110c3ae14a..4b4554fac3 100644 --- a/repos/os/include/usb_session/client.h +++ b/repos/os/include/usb_session/client.h @@ -80,10 +80,16 @@ class Usb::Session_client : public Genode::Rpc_client call(index, alt_setting, interface_descr); } + bool interface_extra(unsigned index, unsigned alt_setting, + Interface_extra *interface_data) override + { + return call(index, alt_setting, interface_data); + } + void endpoint_descriptor(unsigned interface_num, - unsigned alt_setting, - unsigned endpoint_num, - Endpoint_descriptor *endpoint_descr) override + unsigned alt_setting, + unsigned endpoint_num, + Endpoint_descriptor *endpoint_descr) override { call(interface_num, alt_setting, endpoint_num, endpoint_descr); } diff --git a/repos/os/include/usb_session/usb_session.h b/repos/os/include/usb_session/usb_session.h index ee379fc91a..a0e0309303 100644 --- a/repos/os/include/usb_session/usb_session.h +++ b/repos/os/include/usb_session/usb_session.h @@ -182,6 +182,9 @@ struct Usb::Session : public Genode::Session virtual void interface_descriptor(unsigned index, unsigned alt_setting, Interface_descriptor *interface_descr) = 0; + virtual bool interface_extra(unsigned index, unsigned alt_setting, + Interface_extra *interface_data) = 0; + /** * Return endpoint for interface index/alternate setting tuple */ @@ -208,6 +211,8 @@ struct Usb::Session : public Genode::Session GENODE_RPC(Rpc_alt_settings, unsigned, alt_settings, unsigned); GENODE_RPC_THROW(Rpc_iface_descr, void, interface_descriptor, GENODE_TYPE_LIST(Device_not_found, Interface_not_found), unsigned, unsigned, Interface_descriptor *); + GENODE_RPC_THROW(Rpc_iface_extra, bool, interface_extra, GENODE_TYPE_LIST(Device_not_found, + Interface_not_found), unsigned, unsigned, Interface_extra *); GENODE_RPC_THROW(Rpc_ep_descr, void, endpoint_descriptor, GENODE_TYPE_LIST(Device_not_found, Interface_not_found), unsigned, unsigned, unsigned, Endpoint_descriptor *); GENODE_RPC_THROW(Rpc_claim_interface, void, claim_interface, GENODE_TYPE_LIST(Interface_not_found, @@ -215,8 +220,8 @@ struct Usb::Session : public Genode::Session GENODE_RPC_THROW(Rpc_release_interface, void, release_interface, GENODE_TYPE_LIST(Interface_not_found), unsigned); GENODE_RPC_INTERFACE(Rpc_plugged, Rpc_sigh_state_change, Rpc_tx_cap, Rpc_config_descr, - Rpc_iface_descr, Rpc_ep_descr, Rpc_alt_settings, Rpc_claim_interface, - Rpc_release_interface); + Rpc_iface_descr, Rpc_iface_extra, Rpc_ep_descr, Rpc_alt_settings, + Rpc_claim_interface, Rpc_release_interface); }; #endif /* _INCLUDE__USB_SESSION__USB_SESSION_H_ */