mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-22 15:02:25 +00:00
194 lines
5.2 KiB
C
194 lines
5.2 KiB
C
|
/**
|
||
|
* \brief USB session for raw device connection
|
||
|
* \author Sebastian Sumpf
|
||
|
* \date 2014-12-08
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Copyright (C) 2014 Genode Labs GmbH
|
||
|
*
|
||
|
* This file is part of the Genode OS framework, which is distributed
|
||
|
* under the terms of the GNU General Public License version 2.
|
||
|
*/
|
||
|
#ifndef _INCLUDE__USB_SESSION__USB_SESSION_H_
|
||
|
#define _INCLUDE__USB_SESSION__USB_SESSION_H_
|
||
|
|
||
|
#include <os/packet_stream.h>
|
||
|
#include <packet_stream_tx/packet_stream_tx.h>
|
||
|
#include <session/session.h>
|
||
|
#include <usb/types.h>
|
||
|
|
||
|
|
||
|
namespace Usb {
|
||
|
using namespace Genode;
|
||
|
class Session;
|
||
|
struct Packet_descriptor;
|
||
|
struct Completion;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* USB packet type
|
||
|
*/
|
||
|
struct Usb::Packet_descriptor : ::Packet_descriptor
|
||
|
{
|
||
|
enum Type { STRING, CTRL, BULK, IRQ, ALT_SETTING, CONFIG, RELEASE_IF };
|
||
|
|
||
|
Type type;
|
||
|
bool succeded = false;
|
||
|
Completion *completion = nullptr;
|
||
|
|
||
|
union
|
||
|
{
|
||
|
struct
|
||
|
{
|
||
|
uint8_t index;
|
||
|
unsigned length;
|
||
|
} string;
|
||
|
|
||
|
struct
|
||
|
{
|
||
|
uint8_t request;
|
||
|
uint8_t request_type;
|
||
|
uint16_t value;
|
||
|
uint16_t index;
|
||
|
int timeout;
|
||
|
} control;
|
||
|
|
||
|
struct
|
||
|
{
|
||
|
uint8_t ep;
|
||
|
int actual_size; /* returned */
|
||
|
int timeout;
|
||
|
} transfer;
|
||
|
|
||
|
struct
|
||
|
{
|
||
|
uint8_t number;
|
||
|
uint8_t alt_setting;
|
||
|
} interface;
|
||
|
|
||
|
struct
|
||
|
{
|
||
|
uint8_t number;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
bool is_read_transfer() { return transfer.ep & ENDPOINT_IN; }
|
||
|
|
||
|
Packet_descriptor(off_t offset = 0, size_t size = 0)
|
||
|
: ::Packet_descriptor(offset, size) { }
|
||
|
|
||
|
Packet_descriptor(::Packet_descriptor p, Type type, Completion *completion = nullptr)
|
||
|
: ::Packet_descriptor(p.offset(), p.size()), type(type), completion(completion) { }
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Completion for asynchronous communication
|
||
|
*/
|
||
|
struct Usb::Completion
|
||
|
{
|
||
|
virtual void complete(Usb::Packet_descriptor &p) = 0;
|
||
|
};
|
||
|
|
||
|
struct Usb::Session : public Genode::Session
|
||
|
{
|
||
|
/****************
|
||
|
** Exceptions **
|
||
|
****************/
|
||
|
|
||
|
class Device_not_found : public Exception { };
|
||
|
class Interface_not_found : public Exception { };
|
||
|
class Interface_already_claimed : public Exception { };
|
||
|
class Interface_not_claimed : public Exception { };
|
||
|
class Invalid_endpoint : public Exception { };
|
||
|
|
||
|
|
||
|
/*******************
|
||
|
** Packet stream **
|
||
|
*******************/
|
||
|
|
||
|
enum { TX_QUEUE_SIZE = 64 };
|
||
|
|
||
|
typedef Packet_stream_policy<Usb::Packet_descriptor,
|
||
|
TX_QUEUE_SIZE, TX_QUEUE_SIZE,
|
||
|
char> Tx_policy;
|
||
|
|
||
|
typedef Packet_stream_tx::Channel<Tx_policy> Tx;
|
||
|
|
||
|
/**
|
||
|
* Request packet-transmission channel
|
||
|
*/
|
||
|
virtual Tx *tx_channel() { return 0; }
|
||
|
|
||
|
/**
|
||
|
* Request client-side packet-stream interface of tx channel
|
||
|
*/
|
||
|
virtual Tx::Source *source() { return 0; }
|
||
|
|
||
|
|
||
|
/***********************
|
||
|
** Session interface **
|
||
|
***********************/
|
||
|
|
||
|
static const char *service_name() { return "Usb"; }
|
||
|
|
||
|
/**
|
||
|
* Send from the server to the client upon device state change
|
||
|
*/
|
||
|
virtual void sigh_state_change(Signal_context_capability sigh) = 0;
|
||
|
|
||
|
/**
|
||
|
* Is the device present
|
||
|
*/
|
||
|
virtual bool plugged() = 0;
|
||
|
|
||
|
/**
|
||
|
* Retrieve device and current configurations despcriptors
|
||
|
*/
|
||
|
virtual void config_descriptor(Device_descriptor *device_descr,
|
||
|
Config_descriptor *config_descr) = 0;
|
||
|
|
||
|
/**
|
||
|
* Return number of alt settings for iterface
|
||
|
*/
|
||
|
virtual unsigned alt_settings(unsigned index) = 0;
|
||
|
|
||
|
/**
|
||
|
* Return interface descriptor for interface index/alternate setting tuple
|
||
|
*/
|
||
|
virtual void interface_descriptor(unsigned index, unsigned alt_setting,
|
||
|
Interface_descriptor *interface_descr) = 0;
|
||
|
|
||
|
/**
|
||
|
* Return endpoint for interface index/alternate setting tuple
|
||
|
*/
|
||
|
virtual void endpoint_descriptor(unsigned interface_num,
|
||
|
unsigned alt_setting,
|
||
|
unsigned endpoint_num,
|
||
|
Endpoint_descriptor *endpoint_descr) = 0;
|
||
|
|
||
|
/**
|
||
|
* Claim an interface number
|
||
|
*/
|
||
|
virtual void claim_interface(unsigned interface_num) = 0;
|
||
|
|
||
|
GENODE_RPC(Rpc_plugged, bool, plugged);
|
||
|
GENODE_RPC(Rpc_sigh_state_change, void, sigh_state_change, Signal_context_capability);
|
||
|
GENODE_RPC(Rpc_tx_cap, Capability<Tx>, _tx_cap);
|
||
|
GENODE_RPC_THROW(Rpc_config_descr, void, config_descriptor, GENODE_TYPE_LIST(Device_not_found),
|
||
|
Device_descriptor *, Config_descriptor *);
|
||
|
GENODE_RPC(Rpc_alt_settings, unsigned, alt_settings, unsigned);
|
||
|
GENODE_RPC_THROW(Rpc_iface_descr, void, interface_descriptor, GENODE_TYPE_LIST(Device_not_found,
|
||
|
Interface_not_found), unsigned, unsigned, Interface_descriptor *);
|
||
|
GENODE_RPC_THROW(Rpc_ep_descr, void, endpoint_descriptor, GENODE_TYPE_LIST(Device_not_found,
|
||
|
Interface_not_found), unsigned, unsigned, unsigned, Endpoint_descriptor *);
|
||
|
GENODE_RPC_THROW(Rpc_claim_interface, void, claim_interface, GENODE_TYPE_LIST(Interface_not_found,
|
||
|
Interface_already_claimed), unsigned);
|
||
|
GENODE_RPC_THROW(Rpc_release_interface, void, release_interface, GENODE_TYPE_LIST(Interface_not_found),
|
||
|
unsigned);
|
||
|
GENODE_RPC_INTERFACE(Rpc_plugged, Rpc_sigh_state_change, Rpc_tx_cap, Rpc_config_descr,
|
||
|
Rpc_iface_descr, Rpc_ep_descr, Rpc_alt_settings, Rpc_claim_interface);
|
||
|
};
|
||
|
|
||
|
#endif /* _INCLUDE__USB_SESSION__USB_SESSION_H_ */
|