/**
* \brief USB session for USB clients (mainly device drivers)
* \author Stefan Kalkowski
* \author Sebastian Sumpf
* \date 2014-12-08
*/
/*
* Copyright (C) 2014-2024 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 _INCLUDE__USB_SESSION__USB_SESSION_H_
#define _INCLUDE__USB_SESSION__USB_SESSION_H_
#include
#include
#include
#include
#include
#include
namespace Usb {
using namespace Genode;
struct Tagged_packet;
struct Interface_session;
struct Device_session;
class Session;
}
struct Usb::Tagged_packet : Genode::Packet_descriptor
{
/*
* At least on ARM the minimal alignment for distinct
* DMA-capable USB URBs shall meet a maximum cache-line
* size of 128 bytes
*/
enum Alignment { PACKET_ALIGNMENT = 7 };
/**
* Payload location within the packet stream
*/
struct Payload
{
off_t offset;
size_t bytes;
};
struct Tag {
unsigned long value;
} tag { ~0UL };
enum Return_value {
UNHANDLED, NO_DEVICE, INVALID, TIMEOUT, HALT, OK
} return_value { UNHANDLED };
Tagged_packet(off_t offset = 0, size_t size = 0)
: Genode::Packet_descriptor(offset, size) {}
Tagged_packet(Payload p, Tag tag)
:
Genode::Packet_descriptor(p.offset, p.bytes),
tag(tag) {}
};
struct Usb::Interface_session : Interface
{
struct Packet_descriptor : Tagged_packet
{
enum Type {
BULK, IRQ, ISOC, FLUSH
} type { FLUSH };
uint8_t index { 0 };
size_t payload_return_size { 0 };
using Tagged_packet::Tagged_packet;
};
enum { TX_QUEUE_SIZE = 64 };
using Tx_policy = Packet_stream_policy;
using Tx = Packet_stream_tx::Channel;
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_tx_cap, Capability, tx_cap);
GENODE_RPC_INTERFACE(Rpc_tx_cap);
};
struct Usb::Device_session : Interface
{
struct Packet_descriptor : Tagged_packet
{
enum Request : uint8_t {
GET_STATUS = 0x00,
CLEAR_FEATURE = 0x01,
SET_FEATURE = 0x03,
SET_ADDRESS = 0x05,
GET_DESCRIPTOR = 0x06,
SET_DESCRIPTOR = 0x07,
GET_CONFIGURATION = 0x08,
SET_CONFIGURATION = 0x09,
GET_INTERFACE = 0x0a,
SET_INTERFACE = 0x0b,
SYNCH_FRAME = 0x0c,
SET_SEL = 0x30,
SET_ISOCH_DELAY = 0x31,
};
uint8_t request { GET_STATUS };
enum Recipient { DEVICE, IFACE, ENDP, OTHER };
enum Type { STANDARD, CLASS, VENDOR, RESERVED };
enum Direction { OUT, IN };
struct Request_type : Register<8>
{
struct R : Bitfield<0, 5> { };
struct T : Bitfield<5, 2> { };
struct D : Bitfield<7, 1> { };
static access_t value(Recipient r, Type t, Direction d)
{
access_t ret = 0;
R::set(ret, r);
T::set(ret, t);
D::set(ret, d);
return ret;
}
};
Request_type::access_t request_type { 0 };
uint16_t value { 0 };
uint16_t index { 0 };
size_t payload_return_size { 0 };
size_t timeout { 0 };
using Tagged_packet::Tagged_packet;
};
enum { TX_QUEUE_SIZE = 8, TX_BUFFER_SIZE = 4096 };
using Tx_policy = Packet_stream_policy;
using Tx = Packet_stream_tx::Channel;
/*********************
** RPC declaration **
*********************/
GENODE_RPC_THROW(Rpc_acquire_interface, Interface_capability,
acquire_interface,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
uint8_t, size_t);
GENODE_RPC(Rpc_release_interface, void, release_interface,
Interface_capability);
GENODE_RPC(Rpc_tx_cap, Capability, tx_cap);
GENODE_RPC_INTERFACE(Rpc_acquire_interface, Rpc_release_interface,
Rpc_tx_cap);
};
struct Usb::Session : public Genode::Session
{
/**
* \noapi
*/
static const char *service_name() { return "Usb"; }
static constexpr unsigned CAP_QUOTA = 8;
static constexpr unsigned RAM_QUOTA = 512 * 1024;
virtual ~Session() {}
using Device_name = String<64>;
/**
* Request ROM session containing information about available devices.
*
* \return capability to ROM dataspace
*/
virtual Rom_session_capability devices_rom() = 0;
/**
* Acquire device known by unique 'name'
*/
virtual Device_capability acquire_device(Device_name const &name) = 0;
/**
* Acquire the first resp. single device of this session
*/
virtual Device_capability acquire_single_device() = 0;
/**
* Release all resources regarding the given 'device' session
*/
virtual void release_device(Device_capability device) = 0;
/*********************
** RPC declaration **
*********************/
GENODE_RPC(Rpc_devices_rom, Rom_session_capability, devices_rom);
GENODE_RPC_THROW(Rpc_acquire_device, Device_capability, acquire_device,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps),
Device_name const &);
GENODE_RPC_THROW(Rpc_acquire_single_device, Device_capability,
acquire_single_device,
GENODE_TYPE_LIST(Out_of_ram, Out_of_caps));
GENODE_RPC(Rpc_release_device, void, release_device, Device_capability);
GENODE_RPC_INTERFACE(Rpc_devices_rom, Rpc_acquire_device,
Rpc_acquire_single_device, Rpc_release_device);
};
#endif /* _INCLUDE__USB_SESSION__USB_SESSION_H_ */