black_hole: initial support for Usb service

The service is merely announced but trying to request a session always causes a
Service_denied exception. This helps in scenarios where the client is
won't open a session anyway but expects the service to be available. This is
considered a temporary solution.

Ref #4419
This commit is contained in:
Martin Stein 2022-04-07 17:24:36 +02:00 committed by Christian Helmuth
parent 78d7a08618
commit ecd4006514
9 changed files with 155 additions and 0 deletions

View File

@ -9,6 +9,7 @@
<uplink/>
<rom/>
<gpu/>
<usb/>
</provides>
<config>
@ -20,6 +21,7 @@
<uplink/>
<rom/>
<gpu/>
<usb/>
</config>
<content>

View File

@ -30,6 +30,7 @@
<start name="black_hole" caps="100">
<resource name="RAM" quantum="1M"/>
<provides>
<service name="Usb"/>
<service name="Gpu"/>
<service name="ROM"/>
<service name="Uplink"/>
@ -40,6 +41,7 @@
<service name="Audio_out"/>
</provides>
<config>
<usb/>
<gpu/>
<rom/>
<uplink/>
@ -61,6 +63,7 @@
<start name="test-black_hole" caps="200">
<resource name="RAM" quantum="10M"/>
<route>
<service name="Usb"> <child name="black_hole"/> </service>
<service name="Gpu"> <child name="black_hole"/> </service>
<service name="ROM" label="any_label"> <child name="black_hole"/> </service>
<service name="Uplink"> <child name="black_hole"/> </service>

View File

@ -6,4 +6,5 @@ event_session
nic_session
uplink_session
gpu_session
usb_session
os

View File

@ -8,3 +8,4 @@ capture_session
nic_session
uplink_session
gpu_session
usb_session

View File

@ -12,6 +12,7 @@ in the configuration of the component:
* Uplink
* ROM
* Gpu
* Usb
<config>
<audio_in/>
@ -22,4 +23,9 @@ in the configuration of the component:
<uplink/>
<rom/>
<gpu/>
<usb/>
</config>
Be aware, that the USB service is merely announced but always throws a
Service_denied exception when trying to request a session. This is considered
a temporary solution.

View File

@ -4,6 +4,7 @@
<xs:element name="config">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="usb"/>
<xs:element name="gpu"/>
<xs:element name="rom"/>
<xs:element name="uplink"/>

View File

@ -29,6 +29,7 @@
#include "uplink.h"
#include "rom.h"
#include "gpu.h"
#include "usb.h"
/***************
@ -51,6 +52,7 @@ struct Black_hole::Main
Genode::Constructible<Uplink_root> uplink_root { };
Genode::Constructible<Rom_root> rom_root { };
Genode::Constructible<Gpu_root> gpu_root { };
Genode::Constructible<Usb_root> usb_root { };
Main(Genode::Env &env) : env(env)
{
@ -88,6 +90,10 @@ struct Black_hole::Main
gpu_root.construct(env, heap);
env.parent().announce(env.ep().manage(*gpu_root));
}
if (_config_rom.xml().has_sub_node("usb")) {
usb_root.construct(env, heap);
env.parent().announce(env.ep().manage(*usb_root));
}
}
};

View File

@ -0,0 +1,96 @@
/*
* \brief Usb session component and root
* \author Martin Stein
* \date 2022-02-12
*/
/*
* Copyright (C) 2022 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _USB_H_
#define _USB_H_
/* base includes */
#include <root/component.h>
/* os includes */
#include <usb_session/rpc_object.h>
namespace Black_hole {
using namespace Genode;
using namespace Usb;
class Usb_session;
class Usb_root;
}
class Black_hole::Usb_session : public Usb::Session_rpc_object
{
public:
void sigh_state_change(Signal_context_capability /* sigh */) override { }
bool plugged() override { return false; }
void config_descriptor(Device_descriptor * /* device_descr */,
Config_descriptor * /* config_descr */) override { }
unsigned alt_settings(unsigned /* index */) override { return 0; }
void interface_descriptor(unsigned /* index */,
unsigned /* alt_setting */,
Interface_descriptor * /* interface_descr */) override { }
bool interface_extra(unsigned /* index */,
unsigned /* alt_setting */,
Interface_extra * /* interface_data */) override { return false; }
void endpoint_descriptor(unsigned /* interface_num */,
unsigned /* alt_setting */,
unsigned /* endpoint_num */,
Endpoint_descriptor * /* endpoint_descr */) override { }
void claim_interface(unsigned /* interface_num */) override { }
void release_interface(unsigned /* interface_num */) override { }
};
class Black_hole::Usb_root : public Root_component<Usb_session>
{
private:
Env &_env;
protected:
Usb_session *_create_session(char const * /* args */) override
{
/*
* FIXME
*
* Currently, we're fine with a service that is routable but
* not usable. In the long term, this exception should be removed
* and a session object should be returned that can be used as if
* it was a real USB session.
*/
throw Service_denied { };
}
public:
Usb_root(Env &env,
Allocator &alloc)
:
Root_component { env.ep(), alloc },
_env { env }
{ }
};
#endif /* _USB_H_ */

View File

@ -25,6 +25,7 @@
/* os includes */
#include <gpu_session/connection.h>
#include <event_session/connection.h>
#include <usb_session/connection.h>
#include <capture_session/connection.h>
#include <audio_in_session/connection.h>
#include <audio_out_session/connection.h>
@ -41,6 +42,7 @@ namespace Black_hole_test {
class Uplink_test;
class Capture_test;
class Event_test;
class Usb_test;
class Rom_test;
class Main;
}
@ -328,6 +330,41 @@ class Black_hole_test::Rom_test
};
class Black_hole_test::Usb_test
{
private:
Env &_env;
Allocator_avl _alloc;
bool _finished { false };
public:
Usb_test(Env &env,
Heap &heap)
:
_env { env },
_alloc { &heap }
{
try {
Usb::Connection connection { _env, &_alloc };
class Session_request_succeeded { };
throw Session_request_succeeded { };
} catch (Service_denied) {
_finished = true;
}
}
bool finished() const
{
return _finished;
}
};
class Black_hole_test::Main
{
private:
@ -342,6 +379,7 @@ class Black_hole_test::Main
Uplink_test _uplink_test { _env, _heap, _signal_handler };
Capture_test _capture_test { _env };
Event_test _event_test { _env };
Usb_test _usb_test { _env, _heap };
Rom_test _rom_test { _env };
void _handle_signal()
@ -357,6 +395,7 @@ class Black_hole_test::Main
_uplink_test.finished() &&
_capture_test.finished() &&
_event_test.finished() &&
_usb_test.finished() &&
_rom_test.finished()) {
log("Finished");