From b7a379546eda62e461fa907e7c9c26d68b242511 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Mon, 11 Oct 2021 11:23:57 +0200 Subject: [PATCH] genode_c_api: delay USB service announcement Ref #4294 --- repos/os/src/lib/genode_c_api/usb.cc | 31 ++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/repos/os/src/lib/genode_c_api/usb.cc b/repos/os/src/lib/genode_c_api/usb.cc index ddf340bd01..62c4a452e8 100644 --- a/repos/os/src/lib/genode_c_api/usb.cc +++ b/repos/os/src/lib/genode_c_api/usb.cc @@ -140,6 +140,8 @@ class Root : public Root_component Env & _env; Signal_context_capability _sigh_cap; Attached_rom_dataspace _config { _env, "config" }; + Signal_handler _config_handler { _env.ep(), *this, + &Root::_announce_service }; Reporter _reporter { _env, "devices" }; Constructible _devices[MAX_DEVICES]; List> _sessions {}; @@ -180,6 +182,8 @@ class Root : public Root_component */ bool _matches(Device & d, genode_usb_session & s); + void _announce_service(); + public: Root(Env & env, Allocator & alloc, Signal_context_capability); @@ -546,6 +550,27 @@ void ::Root::_report() } +void ::Root::_announce_service() +{ + /* + * Defer the startup of the USB driver until the first configuration + * becomes available. This is needed in scenarios where the configuration + * is dynamically generated and supplied to the USB driver via the + * report-ROM service. + */ + _config.update(); + + if (_announced) + return; + + if (_config.xml().type() == "config") { + log(_config.xml()); + _env.parent().announce(_env.ep().manage(*this)); + _announced = true; + } +} + + void ::Root::announce_device(unsigned long vendor, unsigned long product, unsigned long cla, @@ -557,10 +582,7 @@ void ::Root::announce_device(unsigned long vendor, continue; _devices[idx].construct(vendor, product, cla, bus, dev); - if (!_announced) { - _env.parent().announce(_env.ep().manage(*this)); - _announced = true; - } + _announce_service(); _report(); _for_each_session([&] (genode_usb_session & s) { @@ -637,6 +659,7 @@ bool ::Root::device_associated(genode_usb_session * session, { /* Reserve id zero which is invalid */ _id_alloc.alloc(); + _config.sigh(_config_handler); }