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:
Norman Feske 2019-04-03 16:05:10 +02:00 committed by Christian Helmuth
parent 10c567daee
commit 2208220c12
45 changed files with 385 additions and 526 deletions

View File

@ -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,

View File

@ -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)

View File

@ -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();
}

View File

@ -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

View File

@ -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,

View File

@ -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 :

View File

@ -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(); }
};

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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; }

View File

@ -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 };

View File

@ -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"; }

View File

@ -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"; }

View File

@ -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"; }

View File

@ -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"; }

View File

@ -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;

View File

@ -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:

View File

@ -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;
}

View File

@ -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);

View File

@ -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 };
}
};

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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)) {

View File

@ -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 {

View File

@ -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:

View File

@ -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);
}

View File

@ -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) {

View File

@ -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(); }

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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);
}

View File

@ -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; }
};

View File

@ -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();

View File

@ -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 {

View File

@ -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,

View File

@ -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 { }

View File

@ -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(); }

View File

@ -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()) {

View File

@ -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();

View File

@ -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;