mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-01 08:48:20 +00:00
block session: remove Block::Session::Operations
This patch modernizes the 'Block::Session::info' interface. Instead of using out parameters, the 'init' RPC function returns a compound 'Info' object now. The rather complicated 'Operations' struct is replaced by a 'writeable' attribute in the 'Info' object. Fixes #3275
This commit is contained in:
parent
10c567daee
commit
2208220c12
@ -144,15 +144,11 @@ class Storage_device : public Genode::List<Storage_device>::Element,
|
||||
_capacity();
|
||||
}
|
||||
|
||||
Genode::size_t block_size() { return _block_size; }
|
||||
Block::sector_t block_count() { return _block_count; }
|
||||
|
||||
Block::Session::Operations ops()
|
||||
Block::Session::Info info() const override
|
||||
{
|
||||
Block::Session::Operations o;
|
||||
o.set_operation(Block::Packet_descriptor::READ);
|
||||
o.set_operation(Block::Packet_descriptor::WRITE);
|
||||
return o;
|
||||
return { .block_size = _block_size,
|
||||
.block_count = _block_count,
|
||||
.writeable = true };
|
||||
}
|
||||
|
||||
void read_dma(Block::sector_t block_number,
|
||||
|
@ -29,27 +29,16 @@ class Backend
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Allocator_avl _alloc { &Rump::env().heap() };
|
||||
Block::Connection _session { Rump::env().env(), &_alloc };
|
||||
Genode::size_t _blk_size; /* block size of the device */
|
||||
Block::sector_t _blk_cnt; /* number of blocks of device */
|
||||
Block::Session::Operations _blk_ops;
|
||||
Genode::Lock _session_lock;
|
||||
Genode::Allocator_avl _alloc { &Rump::env().heap() };
|
||||
Block::Connection _session { Rump::env().env(), &_alloc };
|
||||
Block::Session::Info _info { _session.info() };
|
||||
Genode::Lock _session_lock;
|
||||
|
||||
public:
|
||||
|
||||
Backend()
|
||||
{
|
||||
_session.info(&_blk_cnt, &_blk_size, &_blk_ops);
|
||||
}
|
||||
|
||||
uint64_t block_count() const { return (uint64_t)_blk_cnt; }
|
||||
size_t block_size() const { return (size_t)_blk_size; }
|
||||
|
||||
bool writable()
|
||||
{
|
||||
return _blk_ops.supported(Block::Packet_descriptor::WRITE);
|
||||
}
|
||||
uint64_t block_count() const { return _info.block_count; }
|
||||
size_t block_size() const { return _info.block_size; }
|
||||
bool writable() const { return _info.writeable; }
|
||||
|
||||
void sync()
|
||||
{
|
||||
@ -69,8 +58,8 @@ class Backend
|
||||
/* allocate packet */
|
||||
try {
|
||||
Packet_descriptor packet( _session.dma_alloc_packet(length),
|
||||
opcode, offset / _blk_size,
|
||||
length / _blk_size);
|
||||
opcode, offset / _info.block_size,
|
||||
length / _info.block_size);
|
||||
|
||||
/* out packet -> copy data */
|
||||
if (opcode == Packet_descriptor::WRITE)
|
||||
|
@ -32,12 +32,13 @@ struct Gpt::Writer
|
||||
struct Io_error : Genode::Exception { };
|
||||
struct Gpt_invalid : Genode::Exception { };
|
||||
|
||||
using sector_t = Block::sector_t;
|
||||
using sector_t = Block::sector_t;
|
||||
|
||||
Block::Connection &_block;
|
||||
Block::Session::Operations _block_ops { };
|
||||
Block::sector_t _block_count { 0 };
|
||||
size_t _block_size { 0 };
|
||||
Block::Connection &_block;
|
||||
|
||||
Block::Session::Info const _info { _block.info() };
|
||||
size_t const _block_size { _info.block_size };
|
||||
sector_t const _block_count { _info.block_count };
|
||||
|
||||
/*
|
||||
* Blocks available is a crude approximation that _does not_ take
|
||||
@ -653,9 +654,7 @@ struct Gpt::Writer
|
||||
*/
|
||||
Writer(Block::Connection &block, Genode::Xml_node config) : _block(block)
|
||||
{
|
||||
_block.info(&_block_count, &_block_size, &_block_ops);
|
||||
|
||||
if (!_block_ops.supported(Block::Packet_descriptor::WRITE)) {
|
||||
if (!_info.writeable) {
|
||||
Genode::error("cannot write to Block session");
|
||||
throw Io_error();
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ class Http
|
||||
private:
|
||||
|
||||
Genode::Heap &_heap;
|
||||
size_t _size; /* number of bytes in file */
|
||||
size_t _size; /* number of bytes in file */
|
||||
char *_host; /* host name */
|
||||
char *_port; /* host port */
|
||||
char *_path; /* absolute file path on host */
|
||||
@ -95,7 +95,7 @@ class Http
|
||||
*
|
||||
* \return Remote file size in bytes
|
||||
*/
|
||||
size_t file_size() { return _size; }
|
||||
size_t file_size() const { return _size; }
|
||||
|
||||
/**
|
||||
* Set base address of I/O dataspace
|
||||
|
@ -42,14 +42,11 @@ class Driver : public Block::Driver
|
||||
** Block::Driver interface **
|
||||
*******************************/
|
||||
|
||||
Genode::size_t block_size() { return _block_size; }
|
||||
Block::sector_t block_count() { return _http.file_size() / _block_size; }
|
||||
|
||||
Block::Session::Operations ops()
|
||||
Block::Session::Info info() const override
|
||||
{
|
||||
Block::Session::Operations o;
|
||||
o.set_operation(Block::Packet_descriptor::READ);
|
||||
return o;
|
||||
return { .block_size = _block_size,
|
||||
.block_count = _http.file_size() / _block_size,
|
||||
.writeable = false };
|
||||
}
|
||||
|
||||
void read(Block::sector_t block_nr,
|
||||
|
@ -56,17 +56,16 @@ extern "C" {
|
||||
void block_init(Genode::Env &env, Genode::Allocator &alloc) {
|
||||
_platform.construct(env, alloc); }
|
||||
|
||||
struct Drive : Block::Connection
|
||||
struct Drive : private Block::Connection
|
||||
{
|
||||
Block::sector_t block_count;
|
||||
Genode::size_t block_size;
|
||||
Block::Session::Operations ops;
|
||||
Info const info = Block::Connection::info();
|
||||
|
||||
using Block::Connection::tx;
|
||||
using Block::Connection::sync;
|
||||
|
||||
Drive(Platform &platform, char const *label)
|
||||
: Block::Connection(platform.env, &platform.tx_alloc, 128*1024, label)
|
||||
{
|
||||
info(&block_count, &block_size, &ops);
|
||||
}
|
||||
{ }
|
||||
};
|
||||
}
|
||||
|
||||
@ -96,15 +95,8 @@ extern "C" Fatfs::DSTATUS disk_initialize (BYTE drv)
|
||||
|
||||
Drive &drive = *_platform->drives[drv];
|
||||
|
||||
/* check for read- and write-capability */
|
||||
if (!drive.ops.supported(Block::Packet_descriptor::READ)) {
|
||||
Genode::error("drive ", drv, " not readable!");
|
||||
destroy(_platform->alloc, _platform->drives[drv]);
|
||||
_platform->drives[drv] = nullptr;
|
||||
return STA_NOINIT;
|
||||
}
|
||||
|
||||
if (!drive.ops.supported(Block::Packet_descriptor::WRITE))
|
||||
/* check for write-capability */
|
||||
if (!drive.info.writeable)
|
||||
return STA_PROTECT;
|
||||
|
||||
return 0;
|
||||
@ -114,7 +106,7 @@ extern "C" Fatfs::DSTATUS disk_initialize (BYTE drv)
|
||||
extern "C" DSTATUS disk_status (BYTE drv)
|
||||
{
|
||||
if (_platform->drives[drv]) {
|
||||
if (_platform->drives[drv]->ops.supported(Block::Packet_descriptor::WRITE))
|
||||
if (_platform->drives[drv]->info.writeable)
|
||||
return 0;
|
||||
return STA_PROTECT;
|
||||
}
|
||||
@ -130,7 +122,7 @@ extern "C" DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count)
|
||||
|
||||
Drive &drive = *_platform->drives[pdrv];
|
||||
|
||||
Genode::size_t const op_len = drive.block_size*count;
|
||||
Genode::size_t const op_len = drive.info.block_size*count;
|
||||
|
||||
/* allocate packet-descriptor for reading */
|
||||
Block::Packet_descriptor p(drive.tx()->alloc_packet(op_len),
|
||||
@ -160,7 +152,7 @@ extern "C" DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT c
|
||||
|
||||
Drive &drive = *_platform->drives[pdrv];
|
||||
|
||||
Genode::size_t const op_len = drive.block_size*count;
|
||||
Genode::size_t const op_len = drive.info.block_size*count;
|
||||
|
||||
/* allocate packet-descriptor for writing */
|
||||
Block::Packet_descriptor p(drive.tx()->alloc_packet(op_len),
|
||||
@ -198,11 +190,11 @@ extern "C" DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff)
|
||||
return RES_OK;
|
||||
|
||||
case GET_SECTOR_COUNT:
|
||||
*((DWORD*)buff) = drive.block_count;
|
||||
*((DWORD*)buff) = drive.info.block_count;
|
||||
return RES_OK;
|
||||
|
||||
case GET_SECTOR_SIZE:
|
||||
*((WORD*)buff) = drive.block_size;
|
||||
*((WORD*)buff) = drive.info.block_size;
|
||||
return RES_OK;
|
||||
|
||||
case GET_BLOCK_SIZE :
|
||||
|
@ -76,7 +76,8 @@ class Block::Session_component : public Block::Session_component_base,
|
||||
bool _ack_queue_full = false;
|
||||
Packet_descriptor _p_to_handle { };
|
||||
unsigned _p_in_fly;
|
||||
bool _writeable;
|
||||
Info const _info { _driver.info() };
|
||||
bool const _writeable;
|
||||
|
||||
/**
|
||||
* Acknowledge a packet already handled
|
||||
@ -95,7 +96,7 @@ class Block::Session_component : public Block::Session_component_base,
|
||||
*/
|
||||
inline bool _range_check(Packet_descriptor &p) {
|
||||
return p.block_number() + p.block_count() - 1
|
||||
< _driver.block_count(); }
|
||||
< _info.block_count; }
|
||||
|
||||
/**
|
||||
* Handle a single request
|
||||
@ -106,7 +107,9 @@ class Block::Session_component : public Block::Session_component_base,
|
||||
_p_to_handle.succeeded(false);
|
||||
|
||||
/* ignore invalid packets */
|
||||
if (!packet.size() || !_range_check(_p_to_handle) || !tx_sink()->packet_valid(packet)) {
|
||||
bool const valid = packet.size() && _range_check(_p_to_handle)
|
||||
&& tx_sink()->packet_valid(packet);
|
||||
if (!valid) {
|
||||
_ack_packet(_p_to_handle);
|
||||
return;
|
||||
}
|
||||
@ -195,7 +198,7 @@ class Block::Session_component : public Block::Session_component_base,
|
||||
_sink_submit(ep, *this, &Session_component::_signal),
|
||||
_req_queue_full(false),
|
||||
_p_in_fly(0),
|
||||
_writeable(writeable)
|
||||
_writeable(writeable && _info.writeable)
|
||||
{
|
||||
_tx.sigh_ready_to_ack(_sink_ack);
|
||||
_tx.sigh_packet_avail(_sink_submit);
|
||||
@ -239,23 +242,7 @@ class Block::Session_component : public Block::Session_component_base,
|
||||
** Block session interface **
|
||||
*******************************/
|
||||
|
||||
void info(sector_t *blk_count, size_t *blk_size,
|
||||
Operations *ops) override
|
||||
{
|
||||
Operations driver_ops = _driver.ops();
|
||||
|
||||
*blk_count = _driver.block_count();
|
||||
*blk_size = _driver.block_size();
|
||||
*ops = Operations();
|
||||
|
||||
typedef Block::Packet_descriptor::Opcode Opcode;
|
||||
|
||||
if (driver_ops.supported(Opcode::READ))
|
||||
ops->set_operation(Opcode::READ);
|
||||
if (_writeable && driver_ops.supported(Opcode::WRITE))
|
||||
ops->set_operation(Opcode::WRITE);
|
||||
|
||||
}
|
||||
Info info() const override { return _driver.info(); }
|
||||
|
||||
void sync() override { _driver.sync(); }
|
||||
};
|
||||
|
@ -102,19 +102,9 @@ class Block::Driver : Genode::Interface
|
||||
virtual ~Driver() { }
|
||||
|
||||
/**
|
||||
* Request block size for driver and medium
|
||||
* Request block-device information
|
||||
*/
|
||||
virtual Genode::size_t block_size() = 0;
|
||||
|
||||
/**
|
||||
* Request capacity of medium in blocks
|
||||
*/
|
||||
virtual Block::sector_t block_count() = 0;
|
||||
|
||||
/**
|
||||
* Request operations supported by the device
|
||||
*/
|
||||
virtual Session::Operations ops() = 0;
|
||||
virtual Session::Info info() const = 0;
|
||||
|
||||
/**
|
||||
* Read from medium
|
||||
|
@ -39,9 +39,9 @@ class Block::Request_stream : Genode::Noncopyable
|
||||
|
||||
friend class Request_stream;
|
||||
|
||||
Genode::addr_t const _base;
|
||||
Genode::size_t const _size;
|
||||
Genode::uint32_t const _block_size;
|
||||
Genode::addr_t const _base;
|
||||
Genode::size_t const _size;
|
||||
Block::Session::Info const _info;
|
||||
|
||||
/**
|
||||
* Return pointer to the first byte of the request content
|
||||
@ -56,7 +56,7 @@ class Block::Request_stream : Genode::Noncopyable
|
||||
*/
|
||||
Genode::size_t _request_size(Block::Request const &request) const
|
||||
{
|
||||
return request.count * _block_size;
|
||||
return request.count * _info.block_size;
|
||||
}
|
||||
|
||||
bool _valid_range(Block::Request const &request) const
|
||||
@ -77,9 +77,9 @@ class Block::Request_stream : Genode::Noncopyable
|
||||
}
|
||||
|
||||
Payload(Genode::addr_t base, Genode::size_t size,
|
||||
Genode::uint32_t block_size)
|
||||
Block::Session::Info info)
|
||||
:
|
||||
_base(base), _size(size), _block_size(block_size)
|
||||
_base(base), _size(size), _info(info)
|
||||
{ }
|
||||
|
||||
public:
|
||||
@ -101,6 +101,8 @@ class Block::Request_stream : Genode::Noncopyable
|
||||
|
||||
private:
|
||||
|
||||
Block::Session::Info const _info;
|
||||
|
||||
Packet_stream_tx::Rpc_object<Block::Session::Tx> _tx;
|
||||
|
||||
typedef Genode::Packet_stream_sink<Block::Session::Tx_policy> Tx_sink;
|
||||
@ -113,10 +115,11 @@ class Block::Request_stream : Genode::Noncopyable
|
||||
Genode::Dataspace_capability ds,
|
||||
Genode::Entrypoint &ep,
|
||||
Genode::Signal_context_capability sigh,
|
||||
Genode::uint32_t block_size)
|
||||
Block::Session::Info const info)
|
||||
:
|
||||
_info(info),
|
||||
_tx(ds, rm, ep.rpc_ep()),
|
||||
_payload(_tx.sink()->ds_local_base(), _tx.sink()->ds_size(), block_size)
|
||||
_payload(_tx.sink()->ds_local_base(), _tx.sink()->ds_size(), info)
|
||||
{
|
||||
_tx.sigh_ready_to_ack(sigh);
|
||||
_tx.sigh_packet_avail(sigh);
|
||||
@ -130,6 +133,8 @@ class Block::Request_stream : Genode::Noncopyable
|
||||
|
||||
Genode::Capability<Block::Session::Tx> tx_cap() { return _tx.cap(); }
|
||||
|
||||
Block::Session::Info info() const { return _info; }
|
||||
|
||||
/**
|
||||
* Call functor 'fn' with 'Payload' interface as argument
|
||||
*
|
||||
@ -302,7 +307,7 @@ class Block::Request_stream : Genode::Noncopyable
|
||||
|
||||
while (tx_sink.ack_slots_free()) {
|
||||
|
||||
Ack ack(tx_sink, _payload._block_size);
|
||||
Ack ack(tx_sink, _payload._info.block_size);
|
||||
|
||||
fn(ack);
|
||||
|
||||
|
@ -48,8 +48,8 @@ class Block::Packet_descriptor : public Genode::Packet_descriptor
|
||||
|
||||
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 */
|
||||
Genode::size_t _block_count; /* number of blocks of operation */
|
||||
bool _success; /* indicates success of operation */
|
||||
|
||||
public:
|
||||
|
||||
@ -78,7 +78,7 @@ class Block::Packet_descriptor : public Genode::Packet_descriptor
|
||||
Genode::size_t block_count() const { return _block_count; }
|
||||
bool succeeded() const { return _success; }
|
||||
|
||||
void succeeded(bool b) { _success = b ? 1 : 0; }
|
||||
void succeeded(bool b) { _success = b; }
|
||||
};
|
||||
|
||||
|
||||
@ -99,34 +99,19 @@ struct Block::Session : public Genode::Session
|
||||
{
|
||||
enum { TX_QUEUE_SIZE = 256 };
|
||||
|
||||
|
||||
/**
|
||||
* This class represents supported operations on a block device
|
||||
*/
|
||||
class Operations
|
||||
{
|
||||
private:
|
||||
|
||||
unsigned _ops :Packet_descriptor::END; /* bitfield of ops */
|
||||
|
||||
public:
|
||||
|
||||
Operations() : _ops(0) { }
|
||||
|
||||
bool supported(Packet_descriptor::Opcode op) {
|
||||
return (_ops & (1 << op)); }
|
||||
|
||||
void set_operation(Packet_descriptor::Opcode op) {
|
||||
_ops |= (1 << op); }
|
||||
};
|
||||
|
||||
|
||||
typedef Genode::Packet_stream_policy<Block::Packet_descriptor,
|
||||
TX_QUEUE_SIZE, TX_QUEUE_SIZE,
|
||||
char> Tx_policy;
|
||||
|
||||
typedef Packet_stream_tx::Channel<Tx_policy> Tx;
|
||||
|
||||
struct Info
|
||||
{
|
||||
Genode::size_t block_size; /* size of one block in bytes */
|
||||
sector_t block_count; /* number of blocks */
|
||||
bool writeable;
|
||||
};
|
||||
|
||||
/**
|
||||
* \noapi
|
||||
*/
|
||||
@ -138,14 +123,8 @@ struct Block::Session : public Genode::Session
|
||||
|
||||
/**
|
||||
* 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;
|
||||
virtual Info info() const = 0;
|
||||
|
||||
/**
|
||||
* Synchronize with block device, like ensuring data to be written
|
||||
@ -172,8 +151,7 @@ struct Block::Session : public Genode::Session
|
||||
** RPC interface **
|
||||
*******************/
|
||||
|
||||
GENODE_RPC(Rpc_info, void, info, Block::sector_t *,
|
||||
Genode::size_t *, Operations *);
|
||||
GENODE_RPC(Rpc_info, Info, info);
|
||||
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);
|
||||
|
@ -49,11 +49,7 @@ class Block::Session_client : public Genode::Rpc_client<Session>
|
||||
** Block session interface **
|
||||
*****************************/
|
||||
|
||||
void info(sector_t *blk_count, Genode::size_t *blk_size,
|
||||
Operations *ops) override
|
||||
{
|
||||
call<Rpc_info>(blk_count, blk_size, ops);
|
||||
}
|
||||
Info info() const override { return call<Rpc_info>(); }
|
||||
|
||||
Tx *tx_channel() override { return &_tx; }
|
||||
|
||||
|
@ -99,9 +99,7 @@ namespace Test {
|
||||
|
||||
bool _verbose { false };
|
||||
|
||||
Block::Session::Operations _block_ops { };
|
||||
Block::sector_t _block_count { 0 };
|
||||
size_t _block_size { 0 };
|
||||
Block::Session::Info _info { };
|
||||
|
||||
size_t _length_in_blocks { 0 };
|
||||
size_t _size_in_blocks { 0 };
|
||||
|
@ -63,7 +63,7 @@ struct Test::Ping_pong : Test_base
|
||||
while (_blocks < _length_in_blocks && _block->tx()->ready_to_submit()) {
|
||||
|
||||
Block::Packet_descriptor tmp =
|
||||
_block->tx()->alloc_packet(_size_in_blocks * _block_size);
|
||||
_block->tx()->alloc_packet(_size_in_blocks * _info.block_size);
|
||||
|
||||
Block::sector_t const lba = _ping ? _start + _blocks
|
||||
: _end - _blocks;
|
||||
@ -101,7 +101,7 @@ struct Test::Ping_pong : Test_base
|
||||
}
|
||||
|
||||
size_t const psize = p.size();
|
||||
size_t const count = psize / _block_size;
|
||||
size_t const count = psize / _info.block_size;
|
||||
Block::Packet_descriptor::Opcode const op = p.operation();
|
||||
|
||||
/* simulate read */
|
||||
@ -166,8 +166,7 @@ struct Test::Ping_pong : Test_base
|
||||
_block->tx_channel()->sigh_ack_avail(_ack_sigh);
|
||||
_block->tx_channel()->sigh_ready_to_submit(_submit_sigh);
|
||||
|
||||
_block->info(&_block_count, &_block_size, &_block_ops);
|
||||
|
||||
_info = _block->info();
|
||||
_start = _node.attribute_value("start", 0u);
|
||||
_size = _node.attribute_value("size", Number_of_bytes());
|
||||
_length = _node.attribute_value("length", Number_of_bytes());
|
||||
@ -177,13 +176,13 @@ struct Test::Ping_pong : Test_base
|
||||
throw Constructing_test_failed();
|
||||
}
|
||||
|
||||
size_t const total_bytes = _block_count * _block_size;
|
||||
if (_length > total_bytes - (_start * _block_size)) {
|
||||
size_t const total_bytes = _info.block_count * _info.block_size;
|
||||
if (_length > total_bytes - (_start * _info.block_size)) {
|
||||
Genode::error("length too large invalid");
|
||||
throw Constructing_test_failed();
|
||||
}
|
||||
|
||||
if (_block_size > _size || (_size % _block_size) != 0) {
|
||||
if (_info.block_size > _size || (_size % _info.block_size) != 0) {
|
||||
Genode::error("request size invalid");
|
||||
throw Constructing_test_failed();
|
||||
}
|
||||
@ -192,8 +191,8 @@ struct Test::Ping_pong : Test_base
|
||||
_op = Block::Packet_descriptor::WRITE;
|
||||
}
|
||||
|
||||
_size_in_blocks = _size / _block_size;
|
||||
_length_in_blocks = _length / _block_size;
|
||||
_size_in_blocks = _size / _info.block_size;
|
||||
_length_in_blocks = _length / _info.block_size;
|
||||
_end = _start + _length_in_blocks;
|
||||
|
||||
_timer.construct(_env);
|
||||
@ -215,7 +214,7 @@ struct Test::Ping_pong : Test_base
|
||||
_block.destruct();
|
||||
|
||||
return Result(_success, _end_time - _start_time,
|
||||
_bytes, _rx, _tx, _size, _block_size);
|
||||
_bytes, _rx, _tx, _size, _info.block_size);
|
||||
}
|
||||
|
||||
char const *name() const override { return "ping_pong"; }
|
||||
|
@ -115,8 +115,8 @@ struct Test::Random : Test_base
|
||||
{
|
||||
uint64_t r = 0;
|
||||
do {
|
||||
r = _random.get() % _block_count;
|
||||
} while (r + _size_in_blocks > _block_count);
|
||||
r = _random.get() % _info.block_count;
|
||||
} while (r + _size_in_blocks > _info.block_count);
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -178,7 +178,7 @@ struct Test::Random : Test_base
|
||||
}
|
||||
|
||||
size_t const psize = p.size();
|
||||
size_t const count = psize / _block_size;
|
||||
size_t const count = psize / _info.block_size;
|
||||
Block::Packet_descriptor::Opcode const op = p.operation();
|
||||
|
||||
bool const read = op == Block::Packet_descriptor::READ;
|
||||
@ -255,8 +255,7 @@ struct Test::Random : Test_base
|
||||
_block->tx_channel()->sigh_ack_avail(_ack_sigh);
|
||||
_block->tx_channel()->sigh_ready_to_submit(_submit_sigh);
|
||||
|
||||
_block->info(&_block_count, &_block_size, &_block_ops);
|
||||
|
||||
_info = _block->info();
|
||||
_size = _node.attribute_value("size", Number_of_bytes());
|
||||
_length = _node.attribute_value("length", Number_of_bytes());
|
||||
|
||||
@ -270,8 +269,8 @@ struct Test::Random : Test_base
|
||||
throw Constructing_test_failed();
|
||||
}
|
||||
|
||||
if (_block_size > _size || (_size % _block_size) != 0) {
|
||||
Genode::error("request size invalid ", _block_size, " ", _size);
|
||||
if (_info.block_size > _size || (_size % _info.block_size) != 0) {
|
||||
Genode::error("request size invalid ", _info.block_size, " ", _size);
|
||||
throw Constructing_test_failed();
|
||||
}
|
||||
|
||||
@ -285,8 +284,8 @@ struct Test::Random : Test_base
|
||||
|
||||
_alternate_access = w && r;
|
||||
|
||||
_size_in_blocks = _size / _block_size;
|
||||
_length_in_blocks = _length / _block_size;
|
||||
_size_in_blocks = _size / _info.block_size;
|
||||
_length_in_blocks = _length / _info.block_size;
|
||||
|
||||
_timer.construct(_env);
|
||||
|
||||
@ -307,7 +306,7 @@ struct Test::Random : Test_base
|
||||
_block.destruct();
|
||||
|
||||
return Result(_success, _end_time - _start_time,
|
||||
_bytes, _rx, _tx, _size, _block_size);
|
||||
_bytes, _rx, _tx, _size, _info.block_size);
|
||||
}
|
||||
|
||||
char const *name() const override { return "random"; }
|
||||
|
@ -69,7 +69,7 @@ struct Test::Replay : Test_base
|
||||
more = false;
|
||||
requests.dequeue([&] (Request &req) {
|
||||
Block::Packet_descriptor p(
|
||||
_block->tx()->alloc_packet(req.count * _block_size),
|
||||
_block->tx()->alloc_packet(req.count * _info.block_size),
|
||||
req.op, req.nr, req.count);
|
||||
|
||||
bool const write = req.op == Block::Packet_descriptor::WRITE;
|
||||
@ -118,7 +118,7 @@ struct Test::Replay : Test_base
|
||||
}
|
||||
|
||||
size_t const psize = p.size();
|
||||
size_t const count = psize / _block_size;
|
||||
size_t const count = psize / _info.block_size;
|
||||
|
||||
_rx += (p.operation() == Block::Packet_descriptor::READ) * count;
|
||||
_tx += (p.operation() == Block::Packet_descriptor::WRITE) * count;
|
||||
@ -181,7 +181,7 @@ struct Test::Replay : Test_base
|
||||
_block->tx_channel()->sigh_ack_avail(_ack_sigh);
|
||||
_block->tx_channel()->sigh_ready_to_submit(_submit_sigh);
|
||||
|
||||
_block->info(&_block_count, &_block_size, &_block_ops);
|
||||
_info = _block->info();
|
||||
|
||||
_timer.construct(env);
|
||||
|
||||
@ -196,7 +196,7 @@ struct Test::Replay : Test_base
|
||||
_block.destruct();
|
||||
|
||||
return Result(_success, _end_time - _start_time,
|
||||
_bytes, _rx, _tx, 0u, _block_size);
|
||||
_bytes, _rx, _tx, 0u, _info.block_size);
|
||||
}
|
||||
|
||||
char const *name() const override { return "replay"; }
|
||||
|
@ -92,7 +92,7 @@ struct Test::Sequential : Test_base
|
||||
_blocks += _size_in_blocks;
|
||||
|
||||
/* wrap if needed */
|
||||
if (_start >= _block_count) { _start = 0; }
|
||||
if (_start >= _info.block_count) { _start = 0; }
|
||||
|
||||
next = !_synchronous;
|
||||
}
|
||||
@ -124,7 +124,7 @@ struct Test::Sequential : Test_base
|
||||
}
|
||||
|
||||
size_t const psize = p.size();
|
||||
size_t const count = psize / _block_size;
|
||||
size_t const count = psize / _info.block_size;
|
||||
Block::Packet_descriptor::Opcode const op = p.operation();
|
||||
|
||||
_rx += (op == Block::Packet_descriptor::READ) * count;
|
||||
@ -192,7 +192,7 @@ struct Test::Sequential : Test_base
|
||||
_block->tx_channel()->sigh_ack_avail(_ack_sigh);
|
||||
_block->tx_channel()->sigh_ready_to_submit(_submit_sigh);
|
||||
|
||||
_block->info(&_block_count, &_block_size, &_block_ops);
|
||||
_info = _block->info();
|
||||
|
||||
_synchronous = _node.attribute_value("synchronous", false);
|
||||
|
||||
@ -205,7 +205,7 @@ struct Test::Sequential : Test_base
|
||||
throw Constructing_test_failed();
|
||||
}
|
||||
|
||||
if (_block_size > _size || (_size % _block_size) != 0) {
|
||||
if (_info.block_size > _size || (_size % _info.block_size) != 0) {
|
||||
Genode::error("request size invalid");
|
||||
throw Constructing_test_failed();
|
||||
}
|
||||
@ -214,8 +214,8 @@ struct Test::Sequential : Test_base
|
||||
_op = Block::Packet_descriptor::WRITE;
|
||||
}
|
||||
|
||||
_size_in_blocks = _size / _block_size;
|
||||
_length_in_blocks = _length / _block_size;
|
||||
_size_in_blocks = _size / _info.block_size;
|
||||
_length_in_blocks = _length / _info.block_size;
|
||||
|
||||
_timer.construct(_env);
|
||||
|
||||
@ -236,7 +236,7 @@ struct Test::Sequential : Test_base
|
||||
_block.destruct();
|
||||
|
||||
return Result(_success, _end_time - _start_time,
|
||||
_bytes, _rx, _tx, _size, _block_size);
|
||||
_bytes, _rx, _tx, _size, _info.block_size);
|
||||
}
|
||||
|
||||
char const *name() const override { return "sequential"; }
|
||||
|
@ -835,6 +835,9 @@ struct Port_driver : Port, Block::Driver
|
||||
|
||||
virtual void handle_irq() = 0;
|
||||
|
||||
virtual Genode::size_t block_size() const = 0;
|
||||
virtual Block::sector_t block_count() const = 0;
|
||||
|
||||
void state_change()
|
||||
{
|
||||
if (--sem) return;
|
||||
|
@ -182,9 +182,9 @@ struct Ata_driver : Port_driver
|
||||
typedef ::String<Identity::Serial_number> Serial_string;
|
||||
typedef ::String<Identity::Model_number> Model_string;
|
||||
|
||||
Genode::Constructible<Identity> info { };
|
||||
Genode::Constructible<Serial_string> serial { };
|
||||
Genode::Constructible<Model_string> model { };
|
||||
Genode::Constructible<Identity> identity { };
|
||||
Genode::Constructible<Serial_string> serial { };
|
||||
Genode::Constructible<Model_string> model { };
|
||||
|
||||
Io_command *io_cmd = nullptr;
|
||||
Block::Packet_descriptor pending[32];
|
||||
@ -304,14 +304,14 @@ struct Ata_driver : Port_driver
|
||||
if (Port::Is::Dss::get(status)
|
||||
|| Port::Is::Pss::get(status)
|
||||
|| Port::Is::Dhrs::get(status)) {
|
||||
info.construct(device_info);
|
||||
serial.construct(*info);
|
||||
model.construct(*info);
|
||||
identity.construct(device_info);
|
||||
serial.construct(*identity);
|
||||
model.construct(*identity);
|
||||
|
||||
if (verbose) {
|
||||
Genode::log(" model number: ", Genode::Cstring(model->buf));
|
||||
Genode::log(" serial number: ", Genode::Cstring(serial->buf));
|
||||
info->info();
|
||||
identity->info();
|
||||
}
|
||||
|
||||
check_device();
|
||||
@ -340,13 +340,13 @@ struct Ata_driver : Port_driver
|
||||
|
||||
bool ncq_support()
|
||||
{
|
||||
return info->read<Identity::Sata_caps::Ncq_support>() && hba.ncq();
|
||||
return identity->read<Identity::Sata_caps::Ncq_support>() && hba.ncq();
|
||||
}
|
||||
|
||||
void check_device()
|
||||
{
|
||||
cmd_slots = min((int)cmd_slots,
|
||||
info->read<Identity::Queue_depth::Max_depth >() + 1);
|
||||
identity->read<Identity::Queue_depth::Max_depth >() + 1);
|
||||
|
||||
/* no native command queueing */
|
||||
if (!ncq_support())
|
||||
@ -373,12 +373,11 @@ struct Ata_driver : Port_driver
|
||||
|
||||
bool dma_enabled() override { return true; };
|
||||
|
||||
Block::Session::Operations ops() override
|
||||
Block::Session::Info info() const override
|
||||
{
|
||||
Block::Session::Operations o;
|
||||
o.set_operation(Block::Packet_descriptor::READ);
|
||||
o.set_operation(Block::Packet_descriptor::WRITE);
|
||||
return o;
|
||||
return { .block_size = block_size(),
|
||||
.block_count = block_count(),
|
||||
.writeable = true };
|
||||
}
|
||||
|
||||
void read_dma(Block::sector_t block_number,
|
||||
@ -397,19 +396,19 @@ struct Ata_driver : Port_driver
|
||||
io(false, block_number, block_count, phys, packet);
|
||||
}
|
||||
|
||||
Genode::size_t block_size() override
|
||||
Genode::size_t block_size() const override
|
||||
{
|
||||
Genode::size_t size = 512;
|
||||
|
||||
if (info->read<Identity::Logical_block::Longer_512>())
|
||||
size = info->read<Identity::Logical_words>() / 2;
|
||||
if (identity->read<Identity::Logical_block::Longer_512>())
|
||||
size = identity->read<Identity::Logical_words>() / 2;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
Block::sector_t block_count() override
|
||||
Block::sector_t block_count() const override
|
||||
{
|
||||
return info->read<Identity::Sector_count>();
|
||||
return identity->read<Identity::Sector_count>();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -158,6 +158,13 @@ struct Atapi_driver : Port_driver
|
||||
}
|
||||
}
|
||||
|
||||
Block::Session::Info info() const override
|
||||
{
|
||||
return { .block_size = block_size(),
|
||||
.block_count = block_count(),
|
||||
.writeable = false };
|
||||
}
|
||||
|
||||
|
||||
/*****************************
|
||||
** Block::Driver interface **
|
||||
@ -165,19 +172,12 @@ struct Atapi_driver : Port_driver
|
||||
|
||||
bool dma_enabled() override { return true; };
|
||||
|
||||
Block::Session::Operations ops() override
|
||||
{
|
||||
Block::Session::Operations o;
|
||||
o.set_operation(Block::Packet_descriptor::READ);
|
||||
return o;
|
||||
}
|
||||
|
||||
Genode::size_t block_size() override
|
||||
Genode::size_t block_size() const override
|
||||
{
|
||||
return host_to_big_endian(((unsigned *)device_info)[1]);
|
||||
}
|
||||
|
||||
Block::sector_t block_count() override
|
||||
Block::sector_t block_count() const override
|
||||
{
|
||||
return host_to_big_endian(((unsigned *)device_info)[0]) + 1;
|
||||
}
|
||||
|
@ -1408,7 +1408,7 @@ class Driver : public Block::Driver
|
||||
Io_buffer *iob = r->iob;
|
||||
|
||||
if (succeeded && pd.operation() == Packet_descriptor::READ) {
|
||||
size_t const len = pd.block_count() * _block_size;
|
||||
size_t const len = pd.block_count() * _info.block_size;
|
||||
Genode::memcpy(r->buffer, (void*)iob->va, len);
|
||||
}
|
||||
_io_mapper->free(iob);
|
||||
@ -1438,9 +1438,7 @@ class Driver : public Block::Driver
|
||||
** Block **
|
||||
***********/
|
||||
|
||||
size_t _block_size { 0 };
|
||||
Block::sector_t _block_count { 0 };
|
||||
Block::Session::Operations _block_ops { };
|
||||
Block::Session::Info _info { };
|
||||
|
||||
public:
|
||||
|
||||
@ -1541,22 +1539,20 @@ class Driver : public Block::Driver
|
||||
throw Nvme::Controller::Initialization_failed();
|
||||
}
|
||||
|
||||
_block_count = nsinfo.count;
|
||||
_block_size = nsinfo.size;
|
||||
|
||||
_block_ops.set_operation(Packet_descriptor::READ);
|
||||
_block_ops.set_operation(Packet_descriptor::WRITE);
|
||||
_info = { .block_size = nsinfo.size,
|
||||
.block_count = nsinfo.count,
|
||||
.writeable = true };
|
||||
|
||||
Nvme::Controller::Info const &info = _nvme_ctrlr->info();
|
||||
|
||||
Genode::log("NVMe:", info.version.string(), " "
|
||||
Genode::log("NVMe:", info.version.string(), " "
|
||||
"serial:'", info.sn.string(), "'", " "
|
||||
"model:'", info.mn.string(), "'", " "
|
||||
"frev:'", info.fr.string(), "'");
|
||||
|
||||
Genode::log("Block", " "
|
||||
"size:", _block_size, " "
|
||||
"count:", _block_count);
|
||||
"size:", _info.block_size, " "
|
||||
"count:", _info.block_count);
|
||||
|
||||
/* generate Report if requested */
|
||||
try {
|
||||
@ -1577,16 +1573,14 @@ class Driver : public Block::Driver
|
||||
** Block::Driver interface **
|
||||
*******************************/
|
||||
|
||||
size_t block_size() override { return _block_size; }
|
||||
Block::sector_t block_count() override { return _block_count; }
|
||||
Block::Session::Operations ops() override { return _block_ops; }
|
||||
Block::Session::Info info() const override { return _info; }
|
||||
|
||||
void _io(bool write, Block::sector_t lba, size_t count,
|
||||
char *buffer, Packet_descriptor &pd)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
size_t const len = count * _block_size;
|
||||
size_t const len = count * _info.block_size;
|
||||
|
||||
if (_verbose_io) {
|
||||
Genode::error(write ? "write" : "read", " "
|
||||
@ -1686,16 +1680,13 @@ class Driver : public Block::Driver
|
||||
void read(Block::sector_t lba, size_t count,
|
||||
char *buffer, Packet_descriptor &pd) override
|
||||
{
|
||||
if (!_block_ops.supported(Packet_descriptor::READ)) {
|
||||
throw Io_error();
|
||||
}
|
||||
_io(false, lba, count, buffer, pd);
|
||||
}
|
||||
|
||||
void write(Block::sector_t lba, size_t count,
|
||||
char const *buffer, Packet_descriptor &pd) override
|
||||
{
|
||||
if (!_block_ops.supported(Packet_descriptor::WRITE)) {
|
||||
if (!_info.writeable) {
|
||||
throw Io_error();
|
||||
}
|
||||
_io(true, lba, count, const_cast<char*>(buffer), pd);
|
||||
|
@ -28,6 +28,13 @@ namespace Sd_card { class Driver_base; }
|
||||
class Sd_card::Driver_base : public Block::Driver,
|
||||
protected Host_controller
|
||||
{
|
||||
protected:
|
||||
|
||||
Genode::size_t _block_size() const { return 512; }
|
||||
|
||||
Block::sector_t _block_count() const {
|
||||
return card_info().capacity_mb() * 1024 * 2; }
|
||||
|
||||
public:
|
||||
|
||||
Driver_base(Genode::Ram_allocator &ram)
|
||||
@ -37,17 +44,11 @@ class Sd_card::Driver_base : public Block::Driver,
|
||||
** Block::Driver **
|
||||
*******************/
|
||||
|
||||
Genode::size_t block_size() override { return 512; }
|
||||
|
||||
Block::sector_t block_count() override {
|
||||
return card_info().capacity_mb() * 1024 * 2; }
|
||||
|
||||
Block::Session::Operations ops() override
|
||||
Block::Session::Info info() const override
|
||||
{
|
||||
Block::Session::Operations ops;
|
||||
ops.set_operation(Block::Packet_descriptor::READ);
|
||||
ops.set_operation(Block::Packet_descriptor::WRITE);
|
||||
return ops;
|
||||
return { .block_size = _block_size(),
|
||||
.block_count = _block_count(),
|
||||
.writeable = true };
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -246,7 +246,7 @@ bool Driver::_setup_idmac_descriptor_table(size_t block_count,
|
||||
size_t b = block_count;
|
||||
int index = 0;
|
||||
for (index = 0; b; index++, phys_addr += 0x1000, flags = Idmac_desc::NONE) {
|
||||
b = _idmac_desc[index].set(b, block_size(), phys_addr, flags);
|
||||
b = _idmac_desc[index].set(b, _block_size(), phys_addr, flags);
|
||||
_idmac_desc[index].next =
|
||||
_idmac_desc_phys + ((index + 1) * sizeof(Idmac_desc));
|
||||
}
|
||||
@ -260,8 +260,8 @@ bool Driver::_setup_idmac_descriptor_table(size_t block_count,
|
||||
Mmio::write<Bmod::Fixed_burst>(1);
|
||||
Mmio::write<Bmod::Idmac_enable>(1);
|
||||
|
||||
Mmio::write<Blksize>(block_size());
|
||||
Mmio::write<Bytcnt>(block_size() * block_count);
|
||||
Mmio::write<Blksize>(_block_size());
|
||||
Mmio::write<Bytcnt>(_block_size() * block_count);
|
||||
|
||||
Mmio::write<Pldmnd>(1);
|
||||
|
||||
@ -419,7 +419,7 @@ size_t Driver::_read_ext_csd()
|
||||
}
|
||||
|
||||
/* return sector count */
|
||||
uint64_t capacity = csd.Mmio::read<Ext_csd::Sector_count>() * block_size();
|
||||
uint64_t capacity = csd.Mmio::read<Ext_csd::Sector_count>() * _block_size();
|
||||
|
||||
/* to MB */
|
||||
return capacity / (1024 * 1024);
|
||||
|
@ -246,12 +246,12 @@ int Driver::_prepare_dma_mb(Block::Packet_descriptor packet,
|
||||
|
||||
|
||||
/* write ADMA2 table to DMA */
|
||||
size_t const req_size = blk_cnt * block_size();
|
||||
size_t const req_size = blk_cnt * _block_size();
|
||||
if (_adma2_table.setup_request(req_size, buf_phys)) { return -1; }
|
||||
|
||||
/* configure DMA at host */
|
||||
Mmio::write<Adsaddr>(_adma2_table.base_phys());
|
||||
Mmio::write<Blkattr::Blksize>(block_size());
|
||||
Mmio::write<Blkattr::Blksize>(_block_size());
|
||||
Mmio::write<Blkattr::Blkcnt>(blk_cnt);
|
||||
|
||||
_block_transfer.read = reading;
|
||||
@ -396,7 +396,7 @@ Card_info Driver::_init()
|
||||
_delayer.usleep(10000);
|
||||
|
||||
/* configure card to use given block size */
|
||||
if (!issue_command(Set_blocklen(block_size()))) {
|
||||
if (!issue_command(Set_blocklen(_block_size()))) {
|
||||
_detect_err("Set_blocklen command failed"); }
|
||||
|
||||
/* configure host buffer */
|
||||
|
@ -404,7 +404,7 @@ void Driver::read(Block::sector_t block_number,
|
||||
if (_block_transfer.pending) {
|
||||
throw Request_congestion(); }
|
||||
|
||||
Mmio::write<Blk::Blen>(block_size());
|
||||
Mmio::write<Blk::Blen>(_block_size());
|
||||
Mmio::write<Blk::Nblk>(block_count);
|
||||
|
||||
_block_transfer.packet = pkt;
|
||||
@ -414,7 +414,7 @@ void Driver::read(Block::sector_t block_number,
|
||||
error("Read_multiple_block failed");
|
||||
throw Io_error();
|
||||
}
|
||||
size_t const num_accesses = block_count * block_size() /
|
||||
size_t const num_accesses = block_count * _block_size() /
|
||||
sizeof(Data::access_t);
|
||||
Data::access_t *dst = (Data::access_t *)(buffer);
|
||||
|
||||
@ -435,7 +435,7 @@ void Driver::write(Block::sector_t block_number,
|
||||
if (_block_transfer.pending) {
|
||||
throw Request_congestion(); }
|
||||
|
||||
Mmio::write<Blk::Blen>(block_size());
|
||||
Mmio::write<Blk::Blen>(_block_size());
|
||||
Mmio::write<Blk::Nblk>(block_count);
|
||||
|
||||
_block_transfer.packet = pkt;
|
||||
@ -445,7 +445,7 @@ void Driver::write(Block::sector_t block_number,
|
||||
error("Write_multiple_block failed");
|
||||
throw Io_error();
|
||||
}
|
||||
size_t const num_accesses = block_count * block_size() /
|
||||
size_t const num_accesses = block_count * _block_size() /
|
||||
sizeof(Data::access_t);
|
||||
Data::access_t const *src = (Data::access_t const *)(buffer);
|
||||
|
||||
|
@ -191,7 +191,7 @@ void Driver::read(Block::sector_t block_number,
|
||||
Block::Packet_descriptor &packet)
|
||||
{
|
||||
unsigned resp;
|
||||
unsigned length = block_size();
|
||||
unsigned length = _block_size;
|
||||
|
||||
for (size_t i = 0; i < block_count; ++i) {
|
||||
/*
|
||||
@ -200,9 +200,9 @@ void Driver::read(Block::sector_t block_number,
|
||||
* SDSC cards use a byte address as argument while SDHC/SDSC uses a
|
||||
* block address here.
|
||||
*/
|
||||
_read_request(17, (block_number + i) * block_size(),
|
||||
_read_request(17, (block_number + i) * _block_size,
|
||||
length, &resp);
|
||||
_read_data(length, buffer + (i * block_size()));
|
||||
_read_data(length, buffer + (i * _block_size));
|
||||
}
|
||||
ack_packet(packet);
|
||||
}
|
||||
@ -214,7 +214,7 @@ void Driver::write(Block::sector_t block_number,
|
||||
Block::Packet_descriptor &packet)
|
||||
{
|
||||
unsigned resp;
|
||||
unsigned length = block_size();
|
||||
unsigned length = _block_size;
|
||||
|
||||
for (size_t i = 0; i < block_count; ++i) {
|
||||
/*
|
||||
@ -223,18 +223,10 @@ void Driver::write(Block::sector_t block_number,
|
||||
* SDSC cards use a byte address as argument while SDHC/SDSC uses a
|
||||
* block address here.
|
||||
*/
|
||||
_write_request(24, (block_number + i) * block_size(),
|
||||
_write_request(24, (block_number + i) * _block_size,
|
||||
length, &resp);
|
||||
_write_data(length, buffer + (i * block_size()));
|
||||
_write_data(length, buffer + (i * _block_size));
|
||||
}
|
||||
ack_packet(packet);
|
||||
}
|
||||
|
||||
|
||||
Block::Session::Operations Driver::ops()
|
||||
{
|
||||
Block::Session::Operations ops;
|
||||
ops.set_operation(Block::Packet_descriptor::READ);
|
||||
ops.set_operation(Block::Packet_descriptor::WRITE);
|
||||
return ops;
|
||||
}
|
||||
|
@ -110,8 +110,13 @@ class Sd_card::Driver : public Block::Driver, private Attached_mmio
|
||||
void _write_data(unsigned length, char const *buffer);
|
||||
void _write_command(unsigned cmd_index, bool resp);
|
||||
|
||||
public:
|
||||
/*
|
||||
* TODO report (and support) real capacity not just 512M
|
||||
*/
|
||||
size_t const _block_size = 512;
|
||||
Block::sector_t const _block_count = 0x20000000 / _block_size;
|
||||
|
||||
public:
|
||||
|
||||
Driver(Env &env);
|
||||
|
||||
@ -120,8 +125,12 @@ class Sd_card::Driver : public Block::Driver, private Attached_mmio
|
||||
** Block-driver **
|
||||
******************/
|
||||
|
||||
Genode::size_t block_size() override { return 512; }
|
||||
Block::Session::Operations ops() override;
|
||||
Block::Session::Info info() const override
|
||||
{
|
||||
return { .block_size = _block_size,
|
||||
.block_count = _block_count,
|
||||
.writeable = true };
|
||||
}
|
||||
|
||||
void read(Block::sector_t block_number,
|
||||
size_t block_count,
|
||||
@ -133,11 +142,6 @@ class Sd_card::Driver : public Block::Driver, private Attached_mmio
|
||||
char const *buffer,
|
||||
Block::Packet_descriptor &packet) override;
|
||||
|
||||
/*
|
||||
* TODO report (and support) real capacity not just 512M
|
||||
*/
|
||||
Block::sector_t block_count() override {
|
||||
return 0x20000000 / block_size(); }
|
||||
};
|
||||
|
||||
#endif /* _DRIVER_H_ */
|
||||
|
@ -163,7 +163,7 @@ void Driver::_set_block_count(size_t block_count)
|
||||
*/
|
||||
Blksizecnt::access_t v = Mmio::read<Blksizecnt>();
|
||||
Blksizecnt::Blkcnt::set(v, block_count);
|
||||
Blksizecnt::Blksize::set(v, block_size());
|
||||
Blksizecnt::Blksize::set(v, _block_size());
|
||||
Mmio::write<Blksizecnt>(v);
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ size_t Driver::_block_to_command_address(const size_t block_number)
|
||||
{
|
||||
/* use byte position for addressing with standard cards */
|
||||
if (_card_info.version() == Csd3::Version::STANDARD_CAPACITY) {
|
||||
return block_number * block_size();
|
||||
return block_number * _block_size();
|
||||
}
|
||||
return block_number;
|
||||
}
|
||||
@ -276,7 +276,7 @@ void Driver::read(Block::sector_t block_number,
|
||||
throw Io_error(); }
|
||||
|
||||
/* read data from sdhci buffer */
|
||||
for (size_t j = 0; j < block_size() / sizeof(Data::access_t); j++)
|
||||
for (size_t j = 0; j < _block_size() / sizeof(Data::access_t); j++)
|
||||
*dst++ = Mmio::read<Data>();
|
||||
}
|
||||
if (!_poll_and_wait_for<Interrupt::Data_done>(1)) {
|
||||
@ -309,7 +309,7 @@ void Driver::write(Block::sector_t block_number,
|
||||
throw Io_error(); }
|
||||
|
||||
/* write data into sdhci buffer */
|
||||
for (size_t j = 0; j < block_size() / sizeof(Data::access_t); j++)
|
||||
for (size_t j = 0; j < _block_size() / sizeof(Data::access_t); j++)
|
||||
Mmio::write<Data>(*src++);
|
||||
}
|
||||
if (!_poll_and_wait_for<Interrupt::Data_done>(1)) {
|
||||
|
@ -131,9 +131,8 @@ struct Usb::Block_driver : Usb::Completion,
|
||||
/*
|
||||
* Block session
|
||||
*/
|
||||
Block::Session::Operations _block_ops { };
|
||||
Block::sector_t _block_count { 0 };
|
||||
size_t _block_size { 0 };
|
||||
Block::sector_t _block_count { 0 };
|
||||
size_t _block_size { 0 };
|
||||
|
||||
bool _writeable = false;
|
||||
|
||||
@ -723,20 +722,12 @@ struct Usb::Block_driver : Usb::Completion,
|
||||
*/
|
||||
void parse_config(Xml_node node)
|
||||
{
|
||||
_block_ops.set_operation(Block::Packet_descriptor::READ);
|
||||
|
||||
_writeable = node.attribute_value<bool>("writeable", false);
|
||||
if (_writeable)
|
||||
_block_ops.set_operation(Block::Packet_descriptor::WRITE);
|
||||
|
||||
_report_device = node.attribute_value<bool>("report", false);
|
||||
|
||||
active_interface = node.attribute_value<unsigned long>("interface", 0);
|
||||
active_lun = node.attribute_value<unsigned long>("lun", 0);
|
||||
|
||||
reset_device = node.attribute_value<bool>("reset_device", false);
|
||||
|
||||
verbose_scsi = node.attribute_value<bool>("verbose_scsi", false);
|
||||
_writeable = node.attribute_value("writeable", false);
|
||||
_report_device = node.attribute_value("report", false);
|
||||
active_interface = node.attribute_value("interface", 0UL);
|
||||
active_lun = node.attribute_value("lun", 0UL);
|
||||
reset_device = node.attribute_value("reset_device", false);
|
||||
verbose_scsi = node.attribute_value("verbose_scsi", false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -813,9 +804,12 @@ struct Usb::Block_driver : Usb::Completion,
|
||||
** Block::Driver interface **
|
||||
*******************************/
|
||||
|
||||
size_t block_size() override { return _block_size; }
|
||||
Block::sector_t block_count() override { return _block_count; }
|
||||
Block::Session::Operations ops() override { return _block_ops; }
|
||||
Block::Session::Info info() const override
|
||||
{
|
||||
return { .block_size = _block_size,
|
||||
.block_count = _block_count,
|
||||
.writeable = _writeable };
|
||||
}
|
||||
|
||||
void read(Block::sector_t lba, size_t count,
|
||||
char *buffer, Block::Packet_descriptor &p) override {
|
||||
|
@ -36,19 +36,19 @@ class Vfs::Block_file_system : public Single_file_system
|
||||
*/
|
||||
Lock _lock { };
|
||||
|
||||
char *_block_buffer;
|
||||
unsigned _block_buffer_count;
|
||||
char *_block_buffer;
|
||||
unsigned _block_buffer_count;
|
||||
|
||||
Genode::Allocator_avl _tx_block_alloc { &_env.alloc() };
|
||||
Block::Connection _block {
|
||||
Genode::Allocator_avl _tx_block_alloc { &_env.alloc() };
|
||||
|
||||
Block::Connection _block {
|
||||
_env.env(), &_tx_block_alloc, 128*1024, _label.string() };
|
||||
Genode::size_t _block_size = 0;
|
||||
Block::sector_t _block_count = 0;
|
||||
Block::Session::Operations _block_ops { };
|
||||
|
||||
Block::Session::Info const _info { _block.info() };
|
||||
|
||||
Block::Session::Tx::Source *_tx_source;
|
||||
|
||||
bool _readable;
|
||||
bool _writeable;
|
||||
bool _writeable;
|
||||
|
||||
Genode::Signal_receiver _signal_receiver { };
|
||||
Genode::Signal_context _signal_context { };
|
||||
@ -71,12 +71,10 @@ class Vfs::Block_file_system : public Single_file_system
|
||||
unsigned &_block_buffer_count;
|
||||
Genode::Allocator_avl &_tx_block_alloc;
|
||||
Block::Connection &_block;
|
||||
Genode::size_t &_block_size;
|
||||
Block::sector_t &_block_count;
|
||||
Block::Session::Operations &_block_ops;
|
||||
Genode::size_t const _block_size;
|
||||
Block::sector_t const _block_count;
|
||||
Block::Session::Tx::Source *_tx_source;
|
||||
bool &_readable;
|
||||
bool &_writeable;
|
||||
bool const _writeable;
|
||||
Genode::Signal_receiver &_signal_receiver;
|
||||
Genode::Signal_context &_signal_context;
|
||||
Genode::Signal_context_capability &_source_submit_cap;
|
||||
@ -155,12 +153,10 @@ class Vfs::Block_file_system : public Single_file_system
|
||||
unsigned &block_buffer_count,
|
||||
Genode::Allocator_avl &tx_block_alloc,
|
||||
Block::Connection &block,
|
||||
Genode::size_t &block_size,
|
||||
Block::sector_t &block_count,
|
||||
Block::Session::Operations &block_ops,
|
||||
Genode::size_t block_size,
|
||||
Block::sector_t block_count,
|
||||
Block::Session::Tx::Source *tx_source,
|
||||
bool &readable,
|
||||
bool &writeable,
|
||||
bool writeable,
|
||||
Genode::Signal_receiver &signal_receiver,
|
||||
Genode::Signal_context &signal_context,
|
||||
Genode::Signal_context_capability &source_submit_cap)
|
||||
@ -174,9 +170,7 @@ class Vfs::Block_file_system : public Single_file_system
|
||||
_block(block),
|
||||
_block_size(block_size),
|
||||
_block_count(block_count),
|
||||
_block_ops(block_ops),
|
||||
_tx_source(tx_source),
|
||||
_readable(readable),
|
||||
_writeable(writeable),
|
||||
_signal_receiver(signal_receiver),
|
||||
_signal_context(signal_context),
|
||||
@ -186,11 +180,6 @@ class Vfs::Block_file_system : public Single_file_system
|
||||
Read_result read(char *dst, file_size count,
|
||||
file_size &out_count) override
|
||||
{
|
||||
if (!_readable) {
|
||||
Genode::error("block device is not readable");
|
||||
return READ_ERR_INVALID;
|
||||
}
|
||||
|
||||
file_size seek_offset = seek();
|
||||
|
||||
file_size read = 0;
|
||||
@ -343,16 +332,11 @@ class Vfs::Block_file_system : public Single_file_system
|
||||
_block_buffer(0),
|
||||
_block_buffer_count(config.attribute_value("block_buffer_count", 1UL)),
|
||||
_tx_source(_block.tx()),
|
||||
_readable(false),
|
||||
_writeable(false),
|
||||
_writeable(_info.writeable),
|
||||
_source_submit_cap(_signal_receiver.manage(&_signal_context))
|
||||
{
|
||||
_block.info(&_block_count, &_block_size, &_block_ops);
|
||||
|
||||
_readable = _block_ops.supported(Block::Packet_descriptor::READ);
|
||||
_writeable = _block_ops.supported(Block::Packet_descriptor::WRITE);
|
||||
|
||||
_block_buffer = new (_env.alloc()) char[_block_buffer_count * _block_size];
|
||||
_block_buffer = new (_env.alloc())
|
||||
char[_block_buffer_count * _info.block_size];
|
||||
|
||||
_block.tx_channel()->sigh_ready_to_submit(_source_submit_cap);
|
||||
}
|
||||
@ -385,12 +369,10 @@ class Vfs::Block_file_system : public Single_file_system
|
||||
_block_buffer_count,
|
||||
_tx_block_alloc,
|
||||
_block,
|
||||
_block_size,
|
||||
_block_count,
|
||||
_block_ops,
|
||||
_info.block_size,
|
||||
_info.block_count,
|
||||
_tx_source,
|
||||
_readable,
|
||||
_writeable,
|
||||
_info.writeable,
|
||||
_signal_receiver,
|
||||
_signal_context,
|
||||
_source_submit_cap);
|
||||
@ -403,7 +385,7 @@ class Vfs::Block_file_system : public Single_file_system
|
||||
Stat_result stat(char const *path, Stat &out) override
|
||||
{
|
||||
Stat_result const result = Single_file_system::stat(path, out);
|
||||
out.size = _block_count * _block_size;
|
||||
out.size = _info.block_count * _info.block_size;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -423,7 +405,7 @@ class Vfs::Block_file_system : public Single_file_system
|
||||
switch (opcode) {
|
||||
case IOCTL_OP_DIOCGMEDIASIZE:
|
||||
|
||||
out.diocgmediasize.size = _block_count * _block_size;
|
||||
out.diocgmediasize.size = _info.block_count * _info.block_size;
|
||||
return IOCTL_OK;
|
||||
|
||||
default:
|
||||
|
@ -119,9 +119,7 @@ class Driver : public Block::Driver
|
||||
Genode::List<Request> _r_list; /* list of requests */
|
||||
Genode::Packet_allocator _alloc; /* packet allocator */
|
||||
Block::Connection _blk; /* backend device */
|
||||
Block::Session::Operations _ops; /* allowed operations */
|
||||
Genode::size_t _blk_sz; /* block size */
|
||||
Block::sector_t _blk_cnt; /* block count */
|
||||
Block::Session::Info const _info; /* block-device info */
|
||||
Chunk_level_0 _cache; /* chunk hierarchy */
|
||||
Genode::Io_signal_handler<Driver> _source_ack;
|
||||
Genode::Io_signal_handler<Driver> _source_submit;
|
||||
@ -133,7 +131,7 @@ class Driver : public Block::Driver
|
||||
/*
|
||||
* Return modulus of cache's versus backend device's block size
|
||||
*/
|
||||
inline int _cache_blk_mod() { return CACHE_BLK_SIZE / _blk_sz; }
|
||||
inline int _cache_blk_mod() { return CACHE_BLK_SIZE / _info.block_size; }
|
||||
|
||||
/*
|
||||
* Round off given block number to cache block size granularity
|
||||
@ -183,8 +181,8 @@ class Driver : public Block::Driver
|
||||
/* when reading, write result into cache */
|
||||
if (p.operation() == Block::Packet_descriptor::READ)
|
||||
_cache.write(_blk.tx()->packet_content(p),
|
||||
p.block_count() * _blk_sz,
|
||||
p.block_number() * _blk_sz);
|
||||
p.block_count() * _info.block_size,
|
||||
p.block_number() * _info.block_size);
|
||||
|
||||
/* loop through the list of requests, and ack all related */
|
||||
for (Request *r = _r_list.first(), *r_to_handle = r; r;
|
||||
@ -242,11 +240,11 @@ class Driver : public Block::Driver
|
||||
(block_number - nr));
|
||||
|
||||
/* ensure all memory is available before sending the request */
|
||||
_cache.alloc(cnt * _blk_sz, nr * _blk_sz);
|
||||
_cache.alloc(cnt * _info.block_size, nr * _info.block_size);
|
||||
|
||||
/* construct and send the packet */
|
||||
p_to_dev =
|
||||
Block::Packet_descriptor(_blk.dma_alloc_packet(_blk_sz*cnt),
|
||||
Block::Packet_descriptor(_blk.dma_alloc_packet(_info.block_size*cnt),
|
||||
Block::Packet_descriptor::READ,
|
||||
nr, cnt);
|
||||
_r_list.insert(new (&_r_slab) Request(p_to_dev, packet, buffer));
|
||||
@ -266,7 +264,7 @@ class Driver : public Block::Driver
|
||||
void _sync()
|
||||
{
|
||||
Cache::offset_t off = 0;
|
||||
Cache::size_t len = _blk_sz * _blk_cnt;
|
||||
Cache::size_t len = _info.block_size * _info.block_count;
|
||||
|
||||
while (len > 0) {
|
||||
try {
|
||||
@ -278,7 +276,7 @@ class Driver : public Block::Driver
|
||||
* to proceed, so handle signals, until it's ready again
|
||||
*/
|
||||
off = e.off;
|
||||
len = _blk_sz * _blk_cnt - off;
|
||||
len = _info.block_size * _info.block_count - off;
|
||||
_env.ep().wait_and_dispatch_one_io_signal();
|
||||
}
|
||||
}
|
||||
@ -294,8 +292,8 @@ class Driver : public Block::Driver
|
||||
bool _stat(Block::sector_t nr, Genode::size_t cnt,
|
||||
char * const buffer, Block::Packet_descriptor &p)
|
||||
{
|
||||
Cache::offset_t off = nr * _blk_sz;
|
||||
Cache::size_t size = cnt * _blk_sz;
|
||||
Cache::offset_t off = nr * _info.block_size;
|
||||
Cache::size_t size = cnt * _info.block_size;
|
||||
Cache::offset_t end = off + size;
|
||||
|
||||
try {
|
||||
@ -304,7 +302,7 @@ class Driver : public Block::Driver
|
||||
} catch(Cache::Chunk_base::Range_incomplete &e) {
|
||||
off = Genode::max(off, e.off);
|
||||
size = Genode::min(end - off, e.size);
|
||||
_request(off / _blk_sz, size / _blk_sz, buffer, p);
|
||||
_request(off / _info.block_size, size / _info.block_size, buffer, p);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -338,8 +336,7 @@ class Driver : public Block::Driver
|
||||
_r_slab(&heap),
|
||||
_alloc(&heap, CACHE_BLK_SIZE),
|
||||
_blk(_env, &_alloc, Block::Session::TX_QUEUE_SIZE*CACHE_BLK_SIZE),
|
||||
_blk_sz(0),
|
||||
_blk_cnt(0),
|
||||
_info(_blk.info()),
|
||||
_cache(heap, 0),
|
||||
_source_ack(env.ep(), *this, &Driver::_ack_avail),
|
||||
_source_submit(env.ep(), *this, &Driver::_ready_to_submit),
|
||||
@ -347,19 +344,18 @@ class Driver : public Block::Driver
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
_blk.info(&_blk_cnt, &_blk_sz, &_ops);
|
||||
_blk.tx_channel()->sigh_ack_avail(_source_ack);
|
||||
_blk.tx_channel()->sigh_ready_to_submit(_source_submit);
|
||||
env.parent().yield_sigh(_yield);
|
||||
|
||||
if (CACHE_BLK_SIZE % _blk_sz) {
|
||||
if (CACHE_BLK_SIZE % _info.block_size) {
|
||||
error("only devices that block size is divider of ",
|
||||
Hex(CACHE_BLK_SIZE, Hex::OMIT_PREFIX) ," supported");
|
||||
throw Io_error();
|
||||
}
|
||||
|
||||
/* truncate chunk structure to real size of the device */
|
||||
_cache.truncate(_blk_sz*_blk_cnt);
|
||||
_cache.truncate(_info.block_size * _info.block_count);
|
||||
}
|
||||
|
||||
~Driver()
|
||||
@ -370,29 +366,27 @@ class Driver : public Block::Driver
|
||||
}
|
||||
|
||||
Block::Session_client* blk() { return &_blk; }
|
||||
Genode::size_t blk_sz() { return _blk_sz; }
|
||||
Genode::size_t blk_sz() { return _info.block_size; }
|
||||
|
||||
|
||||
/****************************
|
||||
** Block-driver interface **
|
||||
****************************/
|
||||
|
||||
Genode::size_t block_size() { return _blk_sz; }
|
||||
Block::sector_t block_count() { return _blk_cnt; }
|
||||
Block::Session::Operations ops() { return _ops; }
|
||||
Block::Session::Info info() const override { return _info; }
|
||||
|
||||
void read(Block::sector_t block_number,
|
||||
Genode::size_t block_count,
|
||||
char* buffer,
|
||||
Block::Packet_descriptor &packet)
|
||||
{
|
||||
if (!_ops.supported(Block::Packet_descriptor::READ))
|
||||
throw Io_error();
|
||||
|
||||
if (!_stat(block_number, block_count, buffer, packet))
|
||||
return;
|
||||
|
||||
_cache.read(buffer, block_count*_blk_sz, block_number*_blk_sz);
|
||||
_cache.read(buffer,
|
||||
block_count *_info.block_size,
|
||||
block_number*_info.block_size);
|
||||
|
||||
ack_packet(packet);
|
||||
}
|
||||
|
||||
@ -401,10 +395,11 @@ class Driver : public Block::Driver
|
||||
const char * buffer,
|
||||
Block::Packet_descriptor &packet)
|
||||
{
|
||||
if (!_ops.supported(Block::Packet_descriptor::WRITE))
|
||||
if (!_info.writeable)
|
||||
throw Io_error();
|
||||
|
||||
_cache.alloc(block_count * _blk_sz, block_number * _blk_sz);
|
||||
_cache.alloc(block_count * _info.block_size,
|
||||
block_number * _info.block_size);
|
||||
|
||||
if ((block_number % _cache_blk_mod()) &&
|
||||
!_stat(block_number, 1, const_cast<char* const>(buffer), packet))
|
||||
@ -415,8 +410,10 @@ class Driver : public Block::Driver
|
||||
const_cast<char* const>(buffer), packet))
|
||||
return;
|
||||
|
||||
_cache.write(buffer, block_count * _blk_sz,
|
||||
block_number * _blk_sz);
|
||||
_cache.write(buffer,
|
||||
block_count * _info.block_size,
|
||||
block_number * _info.block_size);
|
||||
|
||||
ack_packet(packet);
|
||||
}
|
||||
|
||||
|
@ -40,9 +40,42 @@ class Lx_block_driver : public Block::Driver
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
Block::sector_t _block_count { 0 };
|
||||
Genode::size_t const _block_size { 512 };
|
||||
Block::Session::Operations _block_ops { };
|
||||
Block::Session::Info const _info;
|
||||
|
||||
typedef Genode::String<256> File_name;
|
||||
|
||||
static File_name _file_name(Genode::Xml_node const &config)
|
||||
{
|
||||
return config.attribute_value("file", File_name());
|
||||
}
|
||||
|
||||
static Block::Session::Info _init_info(Genode::Xml_node const &config)
|
||||
{
|
||||
Genode::Number_of_bytes const default_block_size(512);
|
||||
|
||||
if (!config.has_attribute("file")) {
|
||||
Genode::error("mandatory file attribute missing");
|
||||
throw Could_not_open_file();
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
if (stat(_file_name(config).string(), &st)) {
|
||||
perror("stat");
|
||||
throw Could_not_open_file();
|
||||
}
|
||||
|
||||
if (!config.has_attribute("block_size"))
|
||||
Genode::warning("block size missing, assuming ", default_block_size);
|
||||
|
||||
Genode::size_t const block_size =
|
||||
config.attribute_value("block_size", default_block_size);
|
||||
|
||||
return {
|
||||
.block_size = block_size,
|
||||
.block_count = st.st_size / block_size,
|
||||
.writeable = xml_attr_ok(config, "writeable")
|
||||
};
|
||||
}
|
||||
|
||||
int _fd { -1 };
|
||||
|
||||
@ -54,42 +87,20 @@ class Lx_block_driver : public Block::Driver
|
||||
:
|
||||
Block::Driver(env.ram()),
|
||||
_env(env),
|
||||
_block_size(config.attribute_value("block_size", Genode::Number_of_bytes()))
|
||||
_info(_init_info(config))
|
||||
{
|
||||
if (!config.has_attribute("block_size"))
|
||||
Genode::warning("block size missing, assuming 512b");
|
||||
|
||||
bool const writeable = xml_attr_ok(config, "writeable");
|
||||
|
||||
if (!config.has_attribute("file")) {
|
||||
Genode::error("mandatory file attribute missing");
|
||||
throw Could_not_open_file();
|
||||
}
|
||||
|
||||
auto const file = config.attribute_value("file", Genode::String<256>());
|
||||
struct stat st;
|
||||
if (stat(file.string(), &st)) {
|
||||
perror("stat");
|
||||
throw Could_not_open_file();
|
||||
}
|
||||
|
||||
_block_count = st.st_size / _block_size;
|
||||
|
||||
/* open file */
|
||||
_fd = open(file.string(), writeable ? O_RDWR : O_RDONLY);
|
||||
File_name const file_name = _file_name(config);
|
||||
_fd = open(file_name.string(), _info.writeable ? O_RDWR : O_RDONLY);
|
||||
if (_fd == -1) {
|
||||
perror("open");
|
||||
Genode::error("open ", file_name.string());
|
||||
throw Could_not_open_file();
|
||||
}
|
||||
|
||||
_block_ops.set_operation(Block::Packet_descriptor::READ);
|
||||
if (writeable) {
|
||||
_block_ops.set_operation(Block::Packet_descriptor::WRITE);
|
||||
}
|
||||
|
||||
Genode::log("Provide '", file.string(), "' as block device "
|
||||
"block_size: ", _block_size, " block_count: ",
|
||||
_block_count, " writeable: ", writeable ? "yes" : "no");
|
||||
Genode::log("Provide '", file_name, "' as block device "
|
||||
"block_size: ", _info.block_size, " "
|
||||
"block_count: ", _info.block_count, " "
|
||||
"writeable: ", _info.writeable ? "yes" : "no");
|
||||
}
|
||||
|
||||
~Lx_block_driver() { close(_fd); }
|
||||
@ -99,22 +110,15 @@ class Lx_block_driver : public Block::Driver
|
||||
** Block::Driver interface **
|
||||
*****************************/
|
||||
|
||||
Genode::size_t block_size() override { return _block_size; }
|
||||
Block::sector_t block_count() override { return _block_count; }
|
||||
Block::Session::Operations ops() override { return _block_ops; }
|
||||
Block::Session::Info info() const override { return _info; }
|
||||
|
||||
void read(Block::sector_t block_number,
|
||||
Genode::size_t block_count,
|
||||
char *buffer,
|
||||
Block::Packet_descriptor &packet) override
|
||||
{
|
||||
/* range check is done by Block::Driver */
|
||||
if (!_block_ops.supported(Block::Packet_descriptor::READ)) {
|
||||
throw Io_error();
|
||||
}
|
||||
|
||||
off_t const offset = block_number * _block_size;
|
||||
size_t const count = block_count * _block_size;
|
||||
off_t const offset = block_number * _info.block_size;
|
||||
size_t const count = block_count * _info.block_size;
|
||||
|
||||
ssize_t const n = pread(_fd, buffer, count, offset);
|
||||
if (n == -1) {
|
||||
@ -131,12 +135,12 @@ class Lx_block_driver : public Block::Driver
|
||||
Block::Packet_descriptor &packet) override
|
||||
{
|
||||
/* range check is done by Block::Driver */
|
||||
if (!_block_ops.supported(Block::Packet_descriptor::WRITE)) {
|
||||
if (!_info.writeable) {
|
||||
throw Io_error();
|
||||
}
|
||||
|
||||
off_t const offset = block_number * _block_size;
|
||||
size_t const count = block_count * _block_size;
|
||||
off_t const offset = block_number * _info.block_size;
|
||||
size_t const count = block_count * _info.block_size;
|
||||
|
||||
ssize_t const n = pwrite(_fd, buffer, count, offset);
|
||||
if (n == -1) {
|
||||
|
@ -216,21 +216,11 @@ class Block::Session_component : public Block::Session_rpc_object,
|
||||
** Block session interface **
|
||||
*******************************/
|
||||
|
||||
void info(sector_t *blk_count, size_t *blk_size,
|
||||
Operations *ops) override
|
||||
Info info() const override
|
||||
{
|
||||
Operations driver_ops = _driver.ops();
|
||||
|
||||
*blk_count = _partition->sectors;
|
||||
*blk_size = _driver.blk_size();
|
||||
*ops = Operations();
|
||||
|
||||
typedef Block::Packet_descriptor::Opcode Opcode;
|
||||
|
||||
if (driver_ops.supported(Opcode::READ))
|
||||
ops->set_operation(Opcode::READ);
|
||||
if (_writeable && driver_ops.supported(Opcode::WRITE))
|
||||
ops->set_operation(Opcode::WRITE);
|
||||
return Info { .block_size = _driver.blk_size(),
|
||||
.block_count = _partition->sectors,
|
||||
.writeable = _writeable && _driver.writeable() };
|
||||
}
|
||||
|
||||
void sync() override { _driver.session().sync(); }
|
||||
|
@ -81,11 +81,9 @@ class Block::Driver
|
||||
Genode::List<Request> _r_list { };
|
||||
Genode::Allocator_avl _block_alloc;
|
||||
Block::Connection _session;
|
||||
Block::sector_t _blk_cnt = 0;
|
||||
Genode::size_t _blk_size = 0;
|
||||
Block::Session::Info const _info { _session.info() };
|
||||
Genode::Signal_handler<Driver> _source_ack;
|
||||
Genode::Signal_handler<Driver> _source_submit;
|
||||
Block::Session::Operations _ops { };
|
||||
|
||||
void _ready_to_submit();
|
||||
|
||||
@ -115,13 +113,12 @@ class Block::Driver
|
||||
_session(env, &_block_alloc, 4 * 1024 * 1024),
|
||||
_source_ack(env.ep(), *this, &Driver::_ack_avail),
|
||||
_source_submit(env.ep(), *this, &Driver::_ready_to_submit)
|
||||
{
|
||||
_session.info(&_blk_cnt, &_blk_size, &_ops);
|
||||
}
|
||||
{ }
|
||||
|
||||
Genode::size_t blk_size() const { return _info.block_size; }
|
||||
Genode::size_t blk_cnt() const { return _info.block_count; }
|
||||
bool writeable() const { return _info.writeable; }
|
||||
|
||||
Genode::size_t blk_size() { return _blk_size; }
|
||||
Genode::size_t blk_cnt() { return _blk_cnt; }
|
||||
Session::Operations ops() { return _ops; }
|
||||
Session_client& session() { return _session; }
|
||||
|
||||
void work_asynchronously()
|
||||
@ -141,7 +138,7 @@ class Block::Driver
|
||||
Block::Packet_descriptor::Opcode op = write
|
||||
? Block::Packet_descriptor::WRITE
|
||||
: Block::Packet_descriptor::READ;
|
||||
Genode::size_t size = _blk_size * cnt;
|
||||
Genode::size_t const size = _info.block_size * cnt;
|
||||
Packet_descriptor p(_session.dma_alloc_packet(size),
|
||||
op, nr, cnt);
|
||||
Request *r = new (&_r_slab) Request(dispatcher, cli, p);
|
||||
|
@ -112,15 +112,11 @@ class Ram_block : public Block::Driver
|
||||
** Block-driver interface **
|
||||
****************************/
|
||||
|
||||
size_t block_size() override { return _block_size; }
|
||||
Block::sector_t block_count() override { return _block_count; }
|
||||
|
||||
Block::Session::Operations ops() override
|
||||
Block::Session::Info info() const override
|
||||
{
|
||||
Block::Session::Operations o;
|
||||
o.set_operation(Block::Packet_descriptor::READ);
|
||||
o.set_operation(Block::Packet_descriptor::WRITE);
|
||||
return o;
|
||||
return { .block_size = _block_size,
|
||||
.block_count = _block_count,
|
||||
.writeable = true };
|
||||
}
|
||||
|
||||
void read(Block::sector_t block_number,
|
||||
|
@ -44,14 +44,11 @@ class Rom_block : public Block::Driver
|
||||
** Block-driver interface **
|
||||
****************************/
|
||||
|
||||
size_t block_size() override { return _blk_sz; }
|
||||
Block::sector_t block_count() override { return _blk_cnt; }
|
||||
|
||||
Block::Session::Operations ops() override
|
||||
Block::Session::Info info() const override
|
||||
{
|
||||
Block::Session::Operations o;
|
||||
o.set_operation(Block::Packet_descriptor::READ);
|
||||
return o;
|
||||
return { .block_size = _blk_sz,
|
||||
.block_count = _blk_cnt,
|
||||
.writeable = false };
|
||||
}
|
||||
|
||||
void read(Block::sector_t block_number,
|
||||
|
@ -72,9 +72,6 @@ Block_driver::Device::Device(Env &env,
|
||||
{
|
||||
if (_name == Name() || _irq == ~(unsigned)0) {
|
||||
throw Invalid(); }
|
||||
|
||||
_session.info(&_blk_cnt, &_blk_size, &_blk_ops);
|
||||
_writeable = _blk_ops.supported(Packet_descriptor::WRITE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -84,10 +84,7 @@ class Genode::Block_driver
|
||||
Signal_handler<Device> _irq_handler;
|
||||
Block::Connection _session;
|
||||
Id_space<Device>::Element _id_space_elem;
|
||||
size_t _blk_size;
|
||||
Block::sector_t _blk_cnt;
|
||||
Block::Session::Operations _blk_ops;
|
||||
bool _writeable;
|
||||
Block::Session::Info const _info { _session.info() };
|
||||
|
||||
public:
|
||||
|
||||
@ -108,9 +105,9 @@ class Genode::Block_driver
|
||||
|
||||
Request_cache &cache() { return _cache; }
|
||||
Block::Connection &session() { return _session; }
|
||||
size_t block_size() const { return _blk_size; }
|
||||
size_t block_count() const { return _blk_cnt; }
|
||||
bool writeable() const { return _writeable; }
|
||||
size_t block_size() const { return _info.block_size; }
|
||||
size_t block_count() const { return _info.block_count; }
|
||||
bool writeable() const { return _info.writeable; }
|
||||
Name const &name() const { return _name; }
|
||||
unsigned irq() const { return _irq; }
|
||||
};
|
||||
|
@ -53,8 +53,9 @@ class Throughput
|
||||
size_t _bytes = 0;
|
||||
Block::sector_t _current = 0;
|
||||
|
||||
size_t _blk_size = 0;
|
||||
Block::sector_t _blk_count = 0;
|
||||
Block::Session::Info const _info { _session.info() };
|
||||
size_t const _blk_size { _info.block_size };
|
||||
Block::sector_t const _blk_count { _info.block_count };
|
||||
|
||||
void _submit()
|
||||
{
|
||||
@ -138,9 +139,6 @@ class Throughput
|
||||
_session.tx_channel()->sigh_ack_avail(_disp_ack);
|
||||
_session.tx_channel()->sigh_ready_to_submit(_disp_submit);
|
||||
|
||||
Block::Session::Operations blk_ops;
|
||||
_session.info(&_blk_count, &_blk_size, &blk_ops);
|
||||
|
||||
warning("block count ", _blk_count, " size ", _blk_size);
|
||||
log("read/write ", TEST_SIZE / 1024, " KiB ...");
|
||||
_start = _timer.elapsed_ms();
|
||||
|
@ -13,10 +13,10 @@
|
||||
#include <timer_session/connection.h>
|
||||
#include <os/ring_buffer.h>
|
||||
|
||||
static Genode::size_t blk_sz; /* block size of the device */
|
||||
static Block::sector_t test_cnt; /* number test blocks */
|
||||
static Block::sector_t blk_cnt; /* number of blocks of device */
|
||||
static Block::Session::Operations blk_ops; /* supported operations */
|
||||
static Genode::size_t blk_sz; /* block size of the device */
|
||||
static Block::sector_t test_cnt; /* number test blocks */
|
||||
static Block::sector_t blk_cnt; /* number of blocks of device */
|
||||
static bool writeable;
|
||||
|
||||
|
||||
/**
|
||||
@ -281,7 +281,7 @@ struct Write_test : Test
|
||||
|
||||
void perform() override
|
||||
{
|
||||
if (!blk_ops.supported(Block::Packet_descriptor::WRITE))
|
||||
if (!writeable)
|
||||
return;
|
||||
|
||||
Genode::log("read/write/compare block 0 - ", test_cnt - 1,
|
||||
@ -348,7 +348,7 @@ struct Violation_test : Test
|
||||
|
||||
void perform() override
|
||||
{
|
||||
if (!blk_ops.supported(Block::Packet_descriptor::WRITE))
|
||||
if (!writeable)
|
||||
req(0, 1, true);
|
||||
|
||||
req(blk_cnt, 1, false);
|
||||
@ -404,7 +404,12 @@ void Component::construct(Genode::Env &env)
|
||||
{
|
||||
Allocator_avl alloc(&heap);
|
||||
Block::Connection blk(env, &alloc);
|
||||
blk.info(&blk_cnt, &blk_sz, &blk_ops);
|
||||
|
||||
Block::Session::Info const info { blk.info() };
|
||||
|
||||
blk_sz = info.block_size;
|
||||
blk_cnt = info.block_count;
|
||||
writeable = info.writeable;
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -63,15 +63,11 @@ class Driver : public Block::Driver
|
||||
void session_invalidated() override {
|
||||
while (!_packets.empty()) _packets.get(); }
|
||||
|
||||
Genode::size_t block_size() override { return _size; }
|
||||
Block::sector_t block_count() override { return _number; }
|
||||
|
||||
Block::Session::Operations ops() override
|
||||
Block::Session::Info info() const override
|
||||
{
|
||||
Block::Session::Operations ops;
|
||||
ops.set_operation(Block::Packet_descriptor::READ);
|
||||
ops.set_operation(Block::Packet_descriptor::WRITE);
|
||||
return ops;
|
||||
return { .block_size = _size,
|
||||
.block_count = _number,
|
||||
.writeable = true };
|
||||
}
|
||||
|
||||
void read(Block::sector_t block_number,
|
||||
|
@ -41,22 +41,18 @@ struct Test::Block_session_component : Rpc_object<Block::Session>,
|
||||
Entrypoint &ep,
|
||||
Signal_context_capability sigh)
|
||||
:
|
||||
Request_stream(rm, ds, ep, sigh, BLOCK_SIZE), _ep(ep)
|
||||
Request_stream(rm, ds, ep, sigh,
|
||||
Info { .block_size = BLOCK_SIZE,
|
||||
.block_count = NUM_BLOCKS,
|
||||
.writeable = true }),
|
||||
_ep(ep)
|
||||
{
|
||||
_ep.manage(*this);
|
||||
}
|
||||
|
||||
~Block_session_component() { _ep.dissolve(*this); }
|
||||
|
||||
void info(Block::sector_t *count, size_t *block_size, Operations *ops) override
|
||||
{
|
||||
*count = NUM_BLOCKS;
|
||||
*block_size = BLOCK_SIZE;
|
||||
*ops = Operations();
|
||||
|
||||
ops->set_operation(Block::Packet_descriptor::Opcode::READ);
|
||||
ops->set_operation(Block::Packet_descriptor::Opcode::WRITE);
|
||||
}
|
||||
Info info() const override { return Request_stream::info(); }
|
||||
|
||||
void sync() override { }
|
||||
|
||||
|
@ -47,18 +47,16 @@ struct Main
|
||||
log("--- ROM Block test ---");
|
||||
|
||||
Block::Session::Tx::Source &src = *block.tx();
|
||||
size_t blk_sz;
|
||||
Block::sector_t blk_cnt;
|
||||
Block::Session::Operations ops;
|
||||
Block::Session::Info const info = block.info();
|
||||
|
||||
block.info(&blk_cnt, &blk_sz, &ops);
|
||||
if (!ops.supported(Packet_descriptor::READ)) {
|
||||
throw Device_not_readable(); }
|
||||
log("We have ", info.block_count, " blocks with a "
|
||||
"size of ", info.block_size, " bytes");
|
||||
for (size_t i = 0; i < info.block_count; i += REQ_PARALLEL) {
|
||||
|
||||
log("We have ", blk_cnt, " blocks with a size of ", blk_sz, " bytes");
|
||||
for (size_t i = 0; i < blk_cnt; i += REQ_PARALLEL) {
|
||||
size_t cnt = (blk_cnt - i > REQ_PARALLEL) ? REQ_PARALLEL : blk_cnt - i;
|
||||
Packet_descriptor pkt(src.alloc_packet(cnt * blk_sz),
|
||||
size_t const cnt = (info.block_count - i > REQ_PARALLEL)
|
||||
? REQ_PARALLEL : info.block_count - i;
|
||||
|
||||
Packet_descriptor pkt(src.alloc_packet(cnt * info.block_size),
|
||||
Packet_descriptor::READ, i, cnt);
|
||||
|
||||
log("Check blocks ", i, "..", i + cnt - 1);
|
||||
@ -67,7 +65,7 @@ struct Main
|
||||
if (!pkt.succeeded()) {
|
||||
throw Read_request_failed(); }
|
||||
|
||||
char const *rom_src = rom.local_addr<char>() + i * blk_sz;
|
||||
char const *rom_src = rom.local_addr<char>() + i * info.block_size;
|
||||
if (strcmp(rom_src, src.packet_content(pkt), rom.size())) {
|
||||
throw Files_differ(); }
|
||||
|
||||
|
@ -115,11 +115,12 @@ struct Main
|
||||
}
|
||||
/* issue as many requests for the current request size as possible */
|
||||
try {
|
||||
size_t const cnt = req_size() / drv.block_size();
|
||||
size_t const block_size = drv.info().block_size;
|
||||
size_t const cnt = req_size() / block_size;
|
||||
for (; buf_off_pend < buf_size; buf_off_pend += req_size()) {
|
||||
|
||||
/* calculate block offset */
|
||||
addr_t const nr = buf_off_pend / drv.block_size();
|
||||
addr_t const nr = buf_off_pend / block_size;
|
||||
|
||||
if (drv.dma_enabled()) {
|
||||
|
||||
|
@ -63,7 +63,7 @@ Seoul::Disk::Disk(Genode::Env &env, Synced_motherboard &mb,
|
||||
|
||||
/* initialize struct with 0 size */
|
||||
for (int i=0; i < MAX_DISKS; i++) {
|
||||
_diskcon[i].blk_size = 0;
|
||||
_diskcon[i].info.block_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,9 +109,10 @@ void Seoul::Disk::handle_disk(unsigned disknr)
|
||||
} else {
|
||||
|
||||
if (packet.operation() == Block::Packet_descriptor::Opcode::READ) {
|
||||
|
||||
|
||||
unsigned long long sector = msg->sector;
|
||||
sector = (sector-packet.block_number()) * _diskcon[disknr].blk_size;
|
||||
sector = (sector-packet.block_number())
|
||||
* _diskcon[disknr].info.block_size;
|
||||
|
||||
bool const ok = check_dma_descriptors(msg,
|
||||
[&](char * const dma_addr, unsigned i)
|
||||
@ -163,7 +164,7 @@ bool Seoul::Disk::receive(MessageDisk &msg)
|
||||
|
||||
struct disk_session &disk = _diskcon[msg.disknr];
|
||||
|
||||
if (!disk.blk_size) {
|
||||
if (!disk.info.block_size) {
|
||||
Genode::String<16> label("VirtualDisk ", msg.disknr);
|
||||
/*
|
||||
* If we receive a message for this disk the first time, create the
|
||||
@ -185,7 +186,7 @@ bool Seoul::Disk::receive(MessageDisk &msg)
|
||||
return false;
|
||||
}
|
||||
|
||||
disk.blk_con->info(&disk.blk_cnt, &disk.blk_size, &disk.ops);
|
||||
disk.info = disk.blk_con->info();
|
||||
}
|
||||
|
||||
msg.error = MessageDisk::DISK_OK;
|
||||
@ -195,17 +196,17 @@ bool Seoul::Disk::receive(MessageDisk &msg)
|
||||
{
|
||||
Genode::String<16> label("VirtualDisk ", msg.disknr);
|
||||
|
||||
msg.params->flags = DiskParameter::FLAG_HARDDISK;
|
||||
msg.params->sectors = disk.blk_cnt;
|
||||
msg.params->sectorsize = disk.blk_size;
|
||||
msg.params->maxrequestcount = disk.blk_cnt;
|
||||
msg.params->flags = DiskParameter::FLAG_HARDDISK;
|
||||
msg.params->sectors = disk.info.block_count;
|
||||
msg.params->sectorsize = disk.info.block_size;
|
||||
msg.params->maxrequestcount = disk.info.block_count;
|
||||
memcpy(msg.params->name, label.string(), label.length());
|
||||
|
||||
return true;
|
||||
}
|
||||
case MessageDisk::DISK_WRITE:
|
||||
/* don't write on read only medium */
|
||||
if (!disk.ops.supported(Block::Packet_descriptor::WRITE)) {
|
||||
if (!disk.info.writeable) {
|
||||
MessageDiskCommit ro(msg.disknr, msg.usertag,
|
||||
MessageDisk::DISK_STATUS_DEVICE);
|
||||
_motherboard()->bus_diskcommit.send(ro);
|
||||
@ -248,10 +249,10 @@ bool Seoul::Disk::restart(struct disk_session const &disk,
|
||||
{
|
||||
Block::Session::Tx::Source * const source = disk.blk_con->tx();
|
||||
|
||||
unsigned long const total = DmaDescriptor::sum_length(msg->dmacount, msg->dma);
|
||||
unsigned const blk_size = disk.blk_size;
|
||||
unsigned long const blocks = total/blk_size + ((total%blk_size) ? 1 : 0);
|
||||
bool const write = msg->type == MessageDisk::DISK_WRITE;
|
||||
unsigned long const total = DmaDescriptor::sum_length(msg->dmacount, msg->dma);
|
||||
unsigned long const blk_size = disk.info.block_size;
|
||||
unsigned long const blocks = total/blk_size + ((total%blk_size) ? 1 : 0);
|
||||
bool const write = msg->type == MessageDisk::DISK_WRITE;
|
||||
|
||||
Block::Packet_descriptor packet;
|
||||
|
||||
@ -301,8 +302,8 @@ bool Seoul::Disk::execute(bool const write, struct disk_session const &disk,
|
||||
MessageDisk const &msg)
|
||||
{
|
||||
unsigned long long const sector = msg.sector;
|
||||
unsigned long const total = DmaDescriptor::sum_length(msg.dmacount, msg.dma);
|
||||
unsigned long const blk_size = disk.blk_size;
|
||||
unsigned long const total = DmaDescriptor::sum_length(msg.dmacount, msg.dma);
|
||||
unsigned long const blk_size = disk.info.block_size;
|
||||
unsigned long const blocks = total/blk_size + ((total%blk_size) ? 1 : 0);
|
||||
|
||||
Block::Session::Tx::Source * const source = disk.blk_con->tx();
|
||||
|
@ -105,11 +105,9 @@ class Seoul::Disk : public StaticReceiver<Seoul::Disk>
|
||||
/* block session used by disk models of VMM */
|
||||
enum { MAX_DISKS = 4 };
|
||||
struct disk_session {
|
||||
Block::Connection *blk_con;
|
||||
Block::Session::Operations ops;
|
||||
Genode::size_t blk_size;
|
||||
Block::sector_t blk_cnt;
|
||||
Disk_signal *signal;
|
||||
Block::Connection *blk_con;
|
||||
Block::Session::Info info;
|
||||
Disk_signal *signal;
|
||||
} _diskcon[MAX_DISKS] { };
|
||||
|
||||
Synced_motherboard &_motherboard;
|
||||
|
Loading…
x
Reference in New Issue
Block a user