mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-30 16:14:13 +00:00
dde_linux: usb support extra data and zero config
- Vendor devices add addtional data to the config descriptor, read and added to the usb session - allow '0' configuration within the usb session issue #3822
This commit is contained in:
parent
537472e9af
commit
36eeab6df2
@ -441,15 +441,14 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
{
|
||||
usb_host_config *config = _device->udev->actconfig;
|
||||
|
||||
if (!config)
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int err = usb_set_configuration(_device->udev, p.number);
|
||||
|
||||
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -452,15 +452,14 @@ class Usb::Worker : public Genode::Weak_object<Usb::Worker>
|
||||
{
|
||||
usb_host_config *config = _device->udev->actconfig;
|
||||
|
||||
if (!config)
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int err = usb_set_configuration(_device->udev, p.number);
|
||||
|
||||
@ -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,
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -80,6 +80,12 @@ class Usb::Session_client : public Genode::Rpc_client<Session>
|
||||
call<Rpc_iface_descr>(index, alt_setting, interface_descr);
|
||||
}
|
||||
|
||||
bool interface_extra(unsigned index, unsigned alt_setting,
|
||||
Interface_extra *interface_data) override
|
||||
{
|
||||
return call<Rpc_iface_extra>(index, alt_setting, interface_data);
|
||||
}
|
||||
|
||||
void endpoint_descriptor(unsigned interface_num,
|
||||
unsigned alt_setting,
|
||||
unsigned endpoint_num,
|
||||
|
@ -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_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user