genode/repos/os/include/block_session/block_session.h

183 lines
4.6 KiB
C
Raw Normal View History

2011-12-22 15:19:25 +00:00
/*
* \brief Block session interface.
* \author Stefan Kalkowski
* \date 2010-07-06
*/
/*
* Copyright (C) 2010-2017 Genode Labs GmbH
2011-12-22 15:19:25 +00:00
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
2011-12-22 15:19:25 +00:00
*/
#ifndef _INCLUDE__BLOCK_SESSION__BLOCK_SESSION_H_
#define _INCLUDE__BLOCK_SESSION__BLOCK_SESSION_H_
#include <os/packet_stream.h>
#include <packet_stream_tx/packet_stream_tx.h>
#include <session/session.h>
namespace Block {
/**
* Sector type for block session
*/
typedef Genode::uint64_t sector_t;
class Packet_descriptor;
struct Session;
}
2011-12-22 15:19:25 +00:00
/**
* Represents an block-operation request
*
* The data associated with the 'Packet_descriptor' is either
* the data read from or written to the block indicated by
* its number.
*/
class Block::Packet_descriptor : public Genode::Packet_descriptor
{
public:
2011-12-22 15:19:25 +00:00
enum Opcode { READ, WRITE, END };
enum Alignment { PACKET_ALIGNMENT = 11 };
2011-12-22 15:19:25 +00:00
private:
2011-12-22 15:19:25 +00:00
Opcode _op; /* requested operation */
sector_t _block_number; /* requested block number */
Genode::size_t _block_count; /* number of blocks to transfer */
unsigned _success :1; /* indicates success of operation */
2011-12-22 15:19:25 +00:00
public:
2011-12-22 15:19:25 +00:00
/**
* Constructor
*/
Packet_descriptor(Genode::off_t offset=0, Genode::size_t size = 0)
:
Genode::Packet_descriptor(offset, size),
_op(READ), _block_number(0), _block_count(0), _success(false)
{ }
2011-12-22 15:19:25 +00:00
/**
* Constructor
2011-12-22 15:19:25 +00:00
*/
Packet_descriptor(Packet_descriptor p, Opcode op,
sector_t block_number, Genode::size_t block_count = 1)
:
Genode::Packet_descriptor(p.offset(), p.size()),
_op(op), _block_number(block_number),
_block_count(block_count), _success(false)
{ }
2011-12-22 15:19:25 +00:00
Opcode operation() const { return _op; }
sector_t block_number() const { return _block_number; }
Genode::size_t block_count() const { return _block_count; }
bool succeeded() const { return _success; }
2011-12-22 15:19:25 +00:00
void succeeded(bool b) { _success = b ? 1 : 0; }
};
2011-12-22 15:19:25 +00:00
/*
* Block session interface
*
* A block session corresponds to a block device that can be used to read
* or store data. Payload is communicated over the packet-stream interface
* set up between 'Session_client' and 'Session_server'.
*
* Even though the methods 'tx' and 'tx_channel' are specific for the client
* side of the block session interface, they are part of the abstract 'Session'
* class to enable the client-side use of the block interface via a pointer to
* the abstract 'Session' class. This way, we can transparently co-locate the
* packet-stream server with the client in same program.
*/
struct Block::Session : public Genode::Session
{
enum { TX_QUEUE_SIZE = 256 };
2011-12-22 15:19:25 +00:00
/**
* This class represents supported operations on a block device
*/
class Operations
{
private:
2011-12-22 15:19:25 +00:00
unsigned _ops :Packet_descriptor::END; /* bitfield of ops */
2011-12-22 15:19:25 +00:00
public:
2011-12-22 15:19:25 +00:00
Operations() : _ops(0) { }
2011-12-22 15:19:25 +00:00
bool supported(Packet_descriptor::Opcode op) {
return (_ops & (1 << op)); }
2011-12-22 15:19:25 +00:00
void set_operation(Packet_descriptor::Opcode op) {
_ops |= (1 << op); }
};
2011-12-22 15:19:25 +00:00
typedef Genode::Packet_stream_policy<Block::Packet_descriptor,
TX_QUEUE_SIZE, TX_QUEUE_SIZE,
char> Tx_policy;
2011-12-22 15:19:25 +00:00
typedef Packet_stream_tx::Channel<Tx_policy> Tx;
2011-12-22 15:19:25 +00:00
2017-05-24 12:41:19 +00:00
/**
* \noapi
*/
static const char *service_name() { return "Block"; }
2011-12-22 15:19:25 +00:00
enum { CAP_QUOTA = 5 };
virtual ~Session() { }
2011-12-22 15:19:25 +00:00
/**
* Request information about the metrics of the block device
*
* \param block_count will contain the total number of blocks
* \param block_size will contain the size of one block in bytes
* \param ops supported operations
*/
virtual void info(sector_t *block_count,
Genode::size_t *block_size,
Operations *ops) = 0;
/**
* Synchronize with block device, like ensuring data to be written
*/
virtual void sync() = 0;
/**
* Request packet-transmission channel
*/
virtual Tx *tx_channel() { return 0; }
/**
* Request client-side packet-stream interface of tx channel
*/
virtual Tx::Source *tx() { return 0; }
/**
* Return capability for packet-transmission channel
*/
virtual Genode::Capability<Tx> tx_cap() = 0;
/*******************
** RPC interface **
*******************/
GENODE_RPC(Rpc_info, void, info, Block::sector_t *,
Genode::size_t *, Operations *);
GENODE_RPC(Rpc_tx_cap, Genode::Capability<Tx>, tx_cap);
GENODE_RPC(Rpc_sync, void, sync);
GENODE_RPC_INTERFACE(Rpc_info, Rpc_tx_cap, Rpc_sync);
};
2011-12-22 15:19:25 +00:00
#endif /* _INCLUDE__BLOCK_SESSION__BLOCK_SESSION_H_ */