mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 15:18:20 +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:
committed by
Norman Feske
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_notify_peers(void);
|
||||||
|
|
||||||
|
void genode_usb_handle_empty_sessions(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -107,6 +107,11 @@ class genode_usb_session : public Usb::Session_rpc_object
|
|||||||
*/
|
*/
|
||||||
void notify();
|
void notify();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Acknowledge all remaining requests in the packet stream
|
||||||
|
*/
|
||||||
|
void flush_packet_stream();
|
||||||
|
|
||||||
|
|
||||||
/***************************
|
/***************************
|
||||||
** USB session interface **
|
** USB session interface **
|
||||||
@ -228,6 +233,11 @@ class Root : public Root_component<genode_usb_session>
|
|||||||
*/
|
*/
|
||||||
template <typename FUNC>
|
template <typename FUNC>
|
||||||
void session(genode_usb_session_handle_t id, FUNC const & fn);
|
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()
|
bool genode_usb_session::plugged()
|
||||||
{
|
{
|
||||||
genode_usb_bus_num_t bus;
|
genode_usb_bus_num_t bus;
|
||||||
@ -634,8 +660,10 @@ void ::Root::discontinue_device(genode_usb_bus_num_t bus,
|
|||||||
_devices[idx]->dev != dev)
|
_devices[idx]->dev != dev)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (_devices[idx]->usb_session)
|
if (_devices[idx]->usb_session) {
|
||||||
_devices[idx]->usb_session->notify();
|
_devices[idx]->usb_session->notify();
|
||||||
|
_devices[idx]->usb_session->flush_packet_stream();
|
||||||
|
}
|
||||||
|
|
||||||
_devices[idx].destruct();
|
_devices[idx].destruct();
|
||||||
_report();
|
_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::Root(Env & env, Allocator & alloc, Signal_context_capability cap)
|
||||||
:
|
:
|
||||||
Root_component<genode_usb_session>(env.ep(), alloc),
|
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_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);
|
usb_for_each_dev(&work_done, poll_usb_device);
|
||||||
if (work_done)
|
if (work_done)
|
||||||
continue;
|
continue;
|
||||||
|
genode_usb_handle_empty_sessions();
|
||||||
lx_emul_task_schedule(true);
|
lx_emul_task_schedule(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user