mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-07 19:34:56 +00:00
genode_c_api: support to handle empty usb session
Adds a function to the USB part of the Genode's C API, to enable usb_host drivers to acknowledge USB request in client's packet buffer although they are not assigned to an USB device. The requests are marked with a "no device" error. This commit fixes a regression originally solved in genodelabs/genode#4149 Ref genodelabs/genode#4416
This commit is contained in:
parent
c2efa5406e
commit
3c07bf4e86
@ -222,6 +222,8 @@ void genode_usb_ack_request(genode_usb_session_handle_t session_handle,
|
||||
|
||||
void genode_usb_notify_peers(void);
|
||||
|
||||
void genode_usb_handle_empty_sessions(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -107,6 +107,11 @@ class genode_usb_session : public Usb::Session_rpc_object
|
||||
*/
|
||||
void notify();
|
||||
|
||||
/*
|
||||
* Acknowledge all remaining requests in the packet stream
|
||||
*/
|
||||
void flush_packet_stream();
|
||||
|
||||
|
||||
/***************************
|
||||
** USB session interface **
|
||||
@ -228,6 +233,11 @@ class Root : public Root_component<genode_usb_session>
|
||||
*/
|
||||
template <typename FUNC>
|
||||
void session(genode_usb_session_handle_t id, FUNC const & fn);
|
||||
|
||||
/*
|
||||
* Acknowledge requests from sessions without device
|
||||
*/
|
||||
void handle_empty_sessions();
|
||||
};
|
||||
|
||||
|
||||
@ -248,6 +258,22 @@ void genode_usb_session::notify()
|
||||
}
|
||||
|
||||
|
||||
void genode_usb_session::flush_packet_stream()
|
||||
{
|
||||
/* ack packets in flight */
|
||||
for (unsigned idx = 0; idx < MAX_PACKETS_IN_FLY; idx++) {
|
||||
if (!packets[idx].constructed())
|
||||
continue;
|
||||
_ack(Usb::Packet_descriptor::NO_DEVICE_ERROR, *packets[idx]);
|
||||
packets[idx].destruct();
|
||||
}
|
||||
|
||||
/* ack all packets in request stream */
|
||||
while (sink()->packet_avail() && sink()->ack_slots_free())
|
||||
_ack(Usb::Packet_descriptor::NO_DEVICE_ERROR, sink()->get_packet());
|
||||
}
|
||||
|
||||
|
||||
bool genode_usb_session::plugged()
|
||||
{
|
||||
genode_usb_bus_num_t bus;
|
||||
@ -634,8 +660,10 @@ void ::Root::discontinue_device(genode_usb_bus_num_t bus,
|
||||
_devices[idx]->dev != dev)
|
||||
continue;
|
||||
|
||||
if (_devices[idx]->usb_session)
|
||||
if (_devices[idx]->usb_session) {
|
||||
_devices[idx]->usb_session->notify();
|
||||
_devices[idx]->usb_session->flush_packet_stream();
|
||||
}
|
||||
|
||||
_devices[idx].destruct();
|
||||
_report();
|
||||
@ -682,6 +710,18 @@ bool ::Root::device_associated(genode_usb_session * session,
|
||||
}
|
||||
|
||||
|
||||
void ::Root::handle_empty_sessions()
|
||||
{
|
||||
_for_each_session([&] (genode_usb_session & s) {
|
||||
bool associated = false;
|
||||
_for_each_device([&] (Device & d) {
|
||||
if (d.usb_session == &s) associated = true; });
|
||||
if (!associated)
|
||||
s.flush_packet_stream();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
::Root::Root(Env & env, Allocator & alloc, Signal_context_capability cap)
|
||||
:
|
||||
Root_component<genode_usb_session>(env.ep(), alloc),
|
||||
@ -766,3 +806,12 @@ extern "C" void genode_usb_ack_request(genode_usb_session_handle_t session_id,
|
||||
|
||||
|
||||
extern "C" void genode_usb_notify_peers() { }
|
||||
|
||||
|
||||
extern "C" void genode_usb_handle_empty_sessions()
|
||||
{
|
||||
if (!_usb_root)
|
||||
return;
|
||||
|
||||
_usb_root->handle_empty_sessions();
|
||||
}
|
||||
|
@ -473,6 +473,7 @@ static int usb_poll_sessions(void * data)
|
||||
usb_for_each_dev(&work_done, poll_usb_device);
|
||||
if (work_done)
|
||||
continue;
|
||||
genode_usb_handle_empty_sessions();
|
||||
lx_emul_task_schedule(true);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user