block: let generic driver API work asynchronously

Fix #990
This commit is contained in:
Stefan Kalkowski
2013-12-03 15:41:14 +01:00
committed by Norman Feske
parent 9c698ab6c1
commit c3c643bcf1
16 changed files with 289 additions and 311 deletions

View File

@ -40,8 +40,7 @@ class Driver : public Block::Driver
*******************************/ *******************************/
Genode::size_t block_size() { return _block_size; } Genode::size_t block_size() { return _block_size; }
Genode::size_t block_count() { Genode::size_t block_count() { return _http.file_size() / _block_size; }
return _http.file_size() / _block_size; }
Block::Session::Operations ops() Block::Session::Operations ops()
{ {
@ -52,23 +51,13 @@ class Driver : public Block::Driver
void read(Genode::size_t block_nr, void read(Genode::size_t block_nr,
Genode::size_t block_count, Genode::size_t block_count,
char *buffer) { char *buffer,
Block::Packet_descriptor &packet)
{
_http.cmd_get(block_nr * _block_size, block_count * _block_size, _http.cmd_get(block_nr * _block_size, block_count * _block_size,
(addr_t)buffer); } (addr_t)buffer);
session->complete_packet(packet);
void write(Genode::size_t, Genode::size_t, char const*) { }
throw Io_error(); }
void read_dma(Genode::size_t, Genode::size_t, Genode::addr_t) {
throw Io_error(); }
void write_dma(Genode::size_t, Genode::size_t, Genode::addr_t) {
throw Io_error(); }
bool dma_enabled() { return false; }
Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t size) {
return Genode::env()->ram_session()->alloc(size, false); }
void sync() {}
}; };

View File

@ -30,6 +30,21 @@ namespace Block {
class Block::Session_component : public Block::Session_rpc_object class Block::Session_component : public Block::Session_rpc_object
{ {
public:
void complete_packet(Packet_descriptor &packet, bool success = true)
{
packet.succeeded(success);
/* acknowledge packet to the client */
if (!tx_sink()->ready_to_ack()) {
PWRN("need to wait until ready-for-ack");
return;
}
tx_sink()->acknowledge_packet(packet);
}
private: private:
Driver_factory &_driver_factory; Driver_factory &_driver_factory;
@ -60,40 +75,34 @@ class Block::Session_component : public Block::Session_rpc_object
if (_driver.dma_enabled()) if (_driver.dma_enabled())
_driver.read_dma(packet.block_number(), _driver.read_dma(packet.block_number(),
packet.block_count(), packet.block_count(),
_rq_phys + packet.offset()); _rq_phys + packet.offset(),
packet);
else else
_driver.read(packet.block_number(), _driver.read(packet.block_number(),
packet.block_count(), packet.block_count(),
tx_sink()->packet_content(packet)); tx_sink()->packet_content(packet),
packet);
break; break;
case Block::Packet_descriptor::WRITE: case Block::Packet_descriptor::WRITE:
if (_driver.dma_enabled()) if (_driver.dma_enabled())
_driver.write_dma(packet.block_number(), _driver.write_dma(packet.block_number(),
packet.block_count(), packet.block_count(),
_rq_phys + packet.offset()); _rq_phys + packet.offset(),
packet);
else else
_driver.write(packet.block_number(), _driver.write(packet.block_number(),
packet.block_count(), packet.block_count(),
tx_sink()->packet_content(packet)); tx_sink()->packet_content(packet),
packet);
break; break;
default: default:
PWRN("received invalid packet"); throw Driver::Io_error();
packet.succeeded(false);
continue;
} }
} catch (Driver::Io_error) { } catch (Driver::Io_error) {
packet.succeeded(false); complete_packet(packet, false);
} }
/* acknowledge packet to the client */
if (!tx_sink()->ready_to_ack()) {
PWRN("need to wait until ready-for-ack");
return;
}
tx_sink()->acknowledge_packet(packet);
} }
} }
@ -121,6 +130,8 @@ class Block::Session_component : public Block::Session_rpc_object
{ {
_tx.sigh_ready_to_ack(_sink_ack); _tx.sigh_ready_to_ack(_sink_ack);
_tx.sigh_packet_avail(_sink_submit); _tx.sigh_packet_avail(_sink_submit);
driver.session = this;
} }
/** /**

View File

@ -2,6 +2,7 @@
* \brief Block-driver interface * \brief Block-driver interface
* \author Christian Helmuth * \author Christian Helmuth
* \author Sebastian Sumpf * \author Sebastian Sumpf
* \author Stefan kalkowski
* \date 2011-05-23 * \date 2011-05-23
*/ */
@ -17,17 +18,25 @@
#include <base/exception.h> #include <base/exception.h>
#include <base/stdint.h> #include <base/stdint.h>
#include <base/signal.h>
#include <ram_session/ram_session.h> #include <ram_session/ram_session.h>
#include <block_session/block_session.h> #include <block_session/block_session.h>
namespace Block { namespace Block {
class Session_component;
struct Driver;
struct Driver_factory;
};
/**
/**
* Interface to be implemented by the device-specific driver code * Interface to be implemented by the device-specific driver code
*/ */
struct Driver struct Block::Driver
{ {
Session_component *session;
/** /**
* Exceptions * Exceptions
*/ */
@ -53,11 +62,13 @@ namespace Block {
* *
* \param block_number number of first block to read * \param block_number number of first block to read
* \param block_count number of blocks to read * \param block_count number of blocks to read
* \param out_buffer output buffer for read request * \param buffer output buffer for read request
*/ */
virtual void read(Genode::size_t block_number, virtual void read(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char *out_buffer) = 0; char * buffer,
Packet_descriptor &packet) {
throw Io_error(); }
/** /**
* Write to medium * Write to medium
@ -68,7 +79,9 @@ namespace Block {
*/ */
virtual void write(Genode::size_t block_number, virtual void write(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char const *buffer) = 0; const char * buffer,
Packet_descriptor &packet) {
throw Io_error(); }
/** /**
* Read from medium using DMA * Read from medium using DMA
@ -79,7 +92,9 @@ namespace Block {
*/ */
virtual void read_dma(Genode::size_t block_number, virtual void read_dma(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
Genode::addr_t phys) = 0; Genode::addr_t phys,
Packet_descriptor &packet) {
throw Io_error(); }
/** /**
* Write to medium using DMA * Write to medium using DMA
@ -90,32 +105,36 @@ namespace Block {
*/ */
virtual void write_dma(Genode::size_t block_number, virtual void write_dma(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
Genode::addr_t phys) = 0; Genode::addr_t phys,
Packet_descriptor &packet) {
throw Io_error(); }
/** /**
* Check if DMA is enabled for driver * Check if DMA is enabled for driver
* *
* \return true if DMA is enabled, false otherwise * \return true if DMA is enabled, false otherwise
*/ */
virtual bool dma_enabled() = 0; virtual bool dma_enabled() { return false; }
/** /**
* Allocate buffer which is suitable for DMA. * Allocate buffer which is suitable for DMA.
*/ */
virtual Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t) = 0; virtual Genode::Ram_dataspace_capability
alloc_dma_buffer(Genode::size_t size) {
return Genode::env()->ram_session()->alloc(size, false); }
/** /**
* Synchronize with with device. * Synchronize with with device.
*/ */
virtual void sync() = 0; virtual void sync() {}
}; };
/** /**
* Interface for constructing the driver object * Interface for constructing the driver object
*/ */
struct Driver_factory struct Block::Driver_factory
{ {
/** /**
* Construct new driver * Construct new driver
*/ */
@ -125,7 +144,6 @@ namespace Block {
* Destroy driver * Destroy driver
*/ */
virtual void destroy(Driver *driver) = 0; virtual void destroy(Driver *driver) = 0;
}; };
}
#endif /* _BLOCK__DRIVER_H_ */ #endif /* _BLOCK__DRIVER_H_ */

View File

@ -1949,19 +1949,3 @@ int Ahci_driver::_ncq_command(uint64_t lba, unsigned cnt, addr_t phys, bool w)
size_t Ahci_driver::block_count() { return sata_ahci()->block_cnt; } size_t Ahci_driver::block_count() { return sata_ahci()->block_cnt; }
size_t Ahci_driver::block_size() { return Sata_ahci::BLOCK_SIZE; } size_t Ahci_driver::block_size() { return Sata_ahci::BLOCK_SIZE; }
Ram_dataspace_capability Ahci_driver::alloc_dma_buffer(size_t size) {
return env()->ram_session()->alloc(size, 0); }
void Ahci_driver::read(size_t, size_t, char *)
{
PERR("Not implemented");
throw Io_error();
}
void Ahci_driver::write(size_t, size_t, char const *)
{
PERR("Not implemented");
throw Io_error();
}

View File

@ -15,7 +15,7 @@
#define _AHCI_DRIVER_H_ #define _AHCI_DRIVER_H_
/* Genode includes */ /* Genode includes */
#include <block/driver.h> #include <block/component.h>
#include <ram_session/ram_session.h> #include <ram_session/ram_session.h>
/** /**
@ -29,7 +29,6 @@ class Ahci_driver : public Block::Driver
typedef Genode::size_t size_t; typedef Genode::size_t size_t;
typedef Genode::uint64_t uint64_t; typedef Genode::uint64_t uint64_t;
typedef Genode::addr_t addr_t; typedef Genode::addr_t addr_t;
typedef Genode::Ram_dataspace_capability Ram_dataspace_capability;
int _ncq_command(uint64_t lba, unsigned cnt, addr_t phys, bool w); int _ncq_command(uint64_t lba, unsigned cnt, addr_t phys, bool w);
@ -40,28 +39,37 @@ class Ahci_driver : public Block::Driver
*/ */
Ahci_driver(); Ahci_driver();
/***************************** /*****************************
** Block::Driver interface ** ** Block::Driver interface **
*****************************/ *****************************/
Block::Session::Operations ops()
{
Block::Session::Operations o;
o.set_operation(Block::Packet_descriptor::READ);
o.set_operation(Block::Packet_descriptor::WRITE);
return o;
}
size_t block_size(); size_t block_size();
size_t block_count(); size_t block_count();
bool dma_enabled() { return 1; } bool dma_enabled() { return true; }
void write(size_t, size_t, char const *);
void read(size_t, size_t, char *);
Ram_dataspace_capability alloc_dma_buffer(size_t size); void read_dma(size_t block_nr, size_t block_cnt, addr_t phys,
Block::Packet_descriptor &packet)
void read_dma(size_t block_nr, size_t block_cnt, addr_t phys)
{ {
if (_ncq_command(block_nr, block_cnt, phys, 0)) if (_ncq_command(block_nr, block_cnt, phys, 0))
throw Io_error(); throw Io_error();
session->complete_packet(packet);
} }
void write_dma(size_t block_nr, size_t block_cnt, addr_t phys) void write_dma(size_t block_nr, size_t block_cnt, addr_t phys,
Block::Packet_descriptor &packet)
{ {
if (_ncq_command(block_nr, block_cnt, phys, 1)) if (_ncq_command(block_nr, block_cnt, phys, 1))
throw Io_error(); throw Io_error();
session->complete_packet(packet);
} }
}; };

View File

@ -151,10 +151,11 @@ int main(int argc, char **argv)
void operator () (Block::Driver &driver, void operator () (Block::Driver &driver,
addr_t number, size_t count, addr_t phys, char *virt) addr_t number, size_t count, addr_t phys, char *virt)
{ {
Block::Packet_descriptor packet;
if (driver.dma_enabled()) if (driver.dma_enabled())
driver.read_dma(number, count, phys); driver.read_dma(number, count, phys, packet);
else else
driver.read(number, count, virt); driver.read(number, count, virt, packet);
} }
} read_operation; } read_operation;
@ -178,10 +179,11 @@ int main(int argc, char **argv)
void operator () (Block::Driver &driver, void operator () (Block::Driver &driver,
addr_t number, size_t count, addr_t phys, char *virt) addr_t number, size_t count, addr_t phys, char *virt)
{ {
Block::Packet_descriptor packet;
if (driver.dma_enabled()) if (driver.dma_enabled())
driver.write_dma(number, count, phys); driver.write_dma(number, count, phys, packet);
else else
driver.write(number, count, virt); driver.write(number, count, virt, packet);
} }
} write_operation; } write_operation;

View File

@ -34,7 +34,8 @@ class Ahci_driver_base : public Block::Driver
throw Io_error(); throw Io_error();
} }
Ahci_driver_base(Ahci_device * const device) : _device(device) { } Ahci_driver_base(Ahci_device * const device)
: _device(device) { }
public: public:
@ -59,36 +60,26 @@ class Ahci_driver_base : public Block::Driver
void read_dma(size_t block_number, void read_dma(size_t block_number,
size_t block_count, size_t block_count,
addr_t phys) addr_t phys,
Block::Packet_descriptor &packet)
{ {
_sanity_check(block_number, block_count); _sanity_check(block_number, block_count);
_device->read(block_number, block_count, phys); _device->read(block_number, block_count, phys);
if (session) session->complete_packet(packet);
} }
void write_dma(size_t block_number, void write_dma(size_t block_number,
size_t block_count, size_t block_count,
addr_t phys) addr_t phys,
Block::Packet_descriptor &packet)
{ {
_sanity_check(block_number, block_count); _sanity_check(block_number, block_count);
_device->write(block_number, block_count, phys); _device->write(block_number, block_count, phys);
} if (session) session->complete_packet(packet);
void read(size_t, size_t, char *)
{
PERR("%s should not be called", __PRETTY_FUNCTION__);
throw Io_error();
}
void write(size_t, size_t, char const *)
{
PERR("%s should not be called", __PRETTY_FUNCTION__);
throw Io_error();
} }
Ram_dataspace_capability alloc_dma_buffer(size_t size) { Ram_dataspace_capability alloc_dma_buffer(size_t size) {
return _device->alloc_dma_buffer(size); } return _device->alloc_dma_buffer(size); }
void sync() {}
}; };
#endif /* _AHCI_DRIVER_BASE_H_ */ #endif /* _AHCI_DRIVER_BASE_H_ */

View File

@ -16,7 +16,7 @@
#include <base/exception.h> #include <base/exception.h>
#include <base/stdint.h> #include <base/stdint.h>
#include <block/driver.h> #include <block/component.h>
namespace Genode { namespace Genode {
class Io_port_session; class Io_port_session;
@ -120,27 +120,41 @@ namespace Ata {
void read(Genode::size_t block_number, void read(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char *buffer) { char *buffer,
_read(block_number, block_count, buffer, false); } Block::Packet_descriptor &packet)
{
_read(block_number, block_count, buffer, false);
session->complete_packet(packet);
}
void write(Genode::size_t block_number, void write(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char const *buffer) { char const *buffer,
_write(block_number, block_count, buffer, false); } Block::Packet_descriptor &packet)
{
_write(block_number, block_count, buffer, false);
session->complete_packet(packet);
}
void read_dma(Genode::size_t block_number, void read_dma(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
Genode::addr_t phys) { Genode::addr_t phys,
_read(block_number, block_count, (char*)phys, true); } Block::Packet_descriptor &packet)
{
_read(block_number, block_count, (char*)phys, true);
session->complete_packet(packet);
}
void write_dma(Genode::size_t block_number, void write_dma(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
Genode::addr_t phys) { Genode::addr_t phys,
_write(block_number, block_count, (char*)phys, true); } Block::Packet_descriptor &packet)
{
_write(block_number, block_count, (char*)phys, true);
session->complete_packet(packet);
}
bool dma_enabled() { return _dma; } bool dma_enabled() { return _dma; }
Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t size) {
return Genode::env()->ram_session()->alloc(size, false); }
void sync() {}
}; };

View File

@ -36,8 +36,7 @@ enum Commands {
Atapi_device::Atapi_device(unsigned base_cmd, unsigned base_ctrl) Atapi_device::Atapi_device(unsigned base_cmd, unsigned base_ctrl)
: Device(base_cmd, base_ctrl) : Device(base_cmd, base_ctrl) { }
{ }
int Atapi_device::read_sense(unsigned char *sense, int length) int Atapi_device::read_sense(unsigned char *sense, int length)

View File

@ -16,7 +16,6 @@
#include <base/thread.h> #include <base/thread.h>
#include <cap_session/connection.h> #include <cap_session/connection.h>
#include <os/config.h> #include <os/config.h>
#include <block/component.h>
/* local includes */ /* local includes */
#include "ata_device.h" #include "ata_device.h"

View File

@ -99,42 +99,45 @@ class Block::Exynos5_driver : public Block::Driver
void read(Genode::size_t block_number, void read(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char *out_buffer) char *out_buffer,
Packet_descriptor &packet)
{ {
if (!_controller.read_blocks(block_number, block_count, out_buffer)) if (!_controller.read_blocks(block_number, block_count, out_buffer))
throw Io_error(); throw Io_error();
session->complete_packet(packet);
} }
void write(Genode::size_t block_number, void write(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char const *buffer) char const *buffer,
Packet_descriptor &packet)
{ {
if (!_controller.write_blocks(block_number, block_count, buffer)) if (!_controller.write_blocks(block_number, block_count, buffer))
throw Io_error(); throw Io_error();
session->complete_packet(packet);
} }
void read_dma(Genode::size_t block_number, void read_dma(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
Genode::addr_t phys) Genode::addr_t phys,
Packet_descriptor &packet)
{ {
if (!_controller.read_blocks_dma(block_number, block_count, phys)) if (!_controller.read_blocks_dma(block_number, block_count, phys))
throw Io_error(); throw Io_error();
session->complete_packet(packet);
} }
void write_dma(Genode::size_t block_number, void write_dma(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
Genode::addr_t phys) Genode::addr_t phys,
Packet_descriptor &packet)
{ {
if (!_controller.write_blocks_dma(block_number, block_count, phys)) if (!_controller.write_blocks_dma(block_number, block_count, phys))
throw Io_error(); throw Io_error();
session->complete_packet(packet);
} }
bool dma_enabled() { return _use_dma; } bool dma_enabled() { return _use_dma; }
Ram_dataspace_capability alloc_dma_buffer(size_t size) {
return Genode::env()->ram_session()->alloc(size, false); }
void sync() {}
}; };
#endif /* _DRIVER_H_ */ #endif /* _DRIVER_H_ */

View File

@ -111,10 +111,11 @@ int main(int argc, char **argv)
void operator () (Block::Driver &driver, void operator () (Block::Driver &driver,
addr_t number, size_t count, addr_t phys, char *virt) addr_t number, size_t count, addr_t phys, char *virt)
{ {
Block::Packet_descriptor p;
if (driver.dma_enabled()) if (driver.dma_enabled())
driver.read_dma(number, count, phys); driver.read_dma(number, count, phys, p);
else else
driver.read(number, count, virt); driver.read(number, count, virt, p);
} }
} read_operation; } read_operation;
@ -137,10 +138,11 @@ int main(int argc, char **argv)
void operator () (Block::Driver &driver, void operator () (Block::Driver &driver,
addr_t number, size_t count, addr_t phys, char *virt) addr_t number, size_t count, addr_t phys, char *virt)
{ {
Block::Packet_descriptor p;
if (driver.dma_enabled()) if (driver.dma_enabled())
driver.write_dma(number, count, phys); driver.write_dma(number, count, phys, p);
else else
driver.write(number, count, virt); driver.write(number, count, virt, p);
} }
} write_operation; } write_operation;

View File

@ -92,42 +92,45 @@ class Block::Omap4_driver : public Block::Driver
void read(Genode::size_t block_number, void read(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char *out_buffer) char *out_buffer,
Packet_descriptor &packet)
{ {
if (!_controller.read_blocks(block_number, block_count, out_buffer)) if (!_controller.read_blocks(block_number, block_count, out_buffer))
throw Io_error(); throw Io_error();
session->complete_packet(packet);
} }
void write(Genode::size_t block_number, void write(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char const *buffer) char const *buffer,
Packet_descriptor &packet)
{ {
if (!_controller.write_blocks(block_number, block_count, buffer)) if (!_controller.write_blocks(block_number, block_count, buffer))
throw Io_error(); throw Io_error();
session->complete_packet(packet);
} }
void read_dma(Genode::size_t block_number, void read_dma(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
Genode::addr_t phys) Genode::addr_t phys,
Packet_descriptor &packet)
{ {
if (!_controller.read_blocks_dma(block_number, block_count, phys)) if (!_controller.read_blocks_dma(block_number, block_count, phys))
throw Io_error(); throw Io_error();
session->complete_packet(packet);
} }
void write_dma(Genode::size_t block_number, void write_dma(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
Genode::addr_t phys) Genode::addr_t phys,
Packet_descriptor &packet)
{ {
if (!_controller.write_blocks_dma(block_number, block_count, phys)) if (!_controller.write_blocks_dma(block_number, block_count, phys))
throw Io_error(); throw Io_error();
session->complete_packet(packet);
} }
bool dma_enabled() { return _use_dma; } bool dma_enabled() { return _use_dma; }
Ram_dataspace_capability alloc_dma_buffer(size_t size) {
return Genode::env()->ram_session()->alloc(size, false); }
void sync() {}
}; };
#endif /* _DRIVER_H_ */ #endif /* _DRIVER_H_ */

View File

@ -29,7 +29,8 @@ class Sd_card : public Block::Driver
public: public:
Sd_card(Host_driver &host_driver) : _hd(host_driver) Sd_card(Host_driver &host_driver)
: _hd(host_driver)
{ {
unsigned resp; unsigned resp;
@ -89,7 +90,8 @@ class Sd_card : public Block::Driver
void read(Genode::size_t block_number, void read(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char *out_buffer) char *out_buffer,
Block::Packet_descriptor &packet)
{ {
unsigned resp; unsigned resp;
unsigned length = BLOCK_SIZE; unsigned length = BLOCK_SIZE;
@ -105,11 +107,13 @@ class Sd_card : public Block::Driver
length, &resp); length, &resp);
_hd.read_data(length, out_buffer + (i * BLOCK_SIZE)); _hd.read_data(length, out_buffer + (i * BLOCK_SIZE));
} }
session->complete_packet(packet);
} }
void write(Genode::size_t block_number, void write(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char const *buffer) char const *buffer,
Block::Packet_descriptor &packet)
{ {
unsigned resp; unsigned resp;
unsigned length = BLOCK_SIZE; unsigned length = BLOCK_SIZE;
@ -125,26 +129,8 @@ class Sd_card : public Block::Driver
length, &resp); length, &resp);
_hd.write_data(length, buffer + (i * BLOCK_SIZE)); _hd.write_data(length, buffer + (i * BLOCK_SIZE));
} }
session->complete_packet(packet);
} }
/*
* This driver does not support DMA operation, currently.
*/
void read_dma(Genode::size_t, Genode::size_t, Genode::addr_t) {
throw Io_error(); }
void write_dma(Genode::size_t, Genode::size_t, Genode::addr_t) {
throw Io_error(); }
bool dma_enabled() { return false; }
Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t size)
{
return Genode::env()->ram_session()->alloc(size, false);
}
void sync() {}
}; };
#endif /* _SD_CARD_H_ */ #endif /* _SD_CARD_H_ */

View File

@ -59,7 +59,8 @@ class Rom_blk : public Block::Driver
void read(Genode::size_t block_number, void read(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char *out_buffer) char* buffer,
Block::Packet_descriptor &packet)
{ {
/* sanity check block number */ /* sanity check block number */
if ((block_number + block_count > _file_sz / _blk_sz) if ((block_number + block_count > _file_sz / _blk_sz)
@ -73,32 +74,10 @@ class Rom_blk : public Block::Driver
size_t size = block_count * _blk_sz; size_t size = block_count * _blk_sz;
/* copy file content to packet payload */ /* copy file content to packet payload */
memcpy(out_buffer, (void*)(_file_addr + offset), size); memcpy((void*)buffer, (void*)(_file_addr + offset), size);
session->complete_packet(packet);
} }
void write(Genode::size_t block_number,
Genode::size_t block_count,
char const *buffer)
{
PWRN("write attempt on read-only device");
}
/*
* This driver does not support DMA operation, currently.
*/
void read_dma(Genode::size_t, Genode::size_t, Genode::addr_t) {
throw Io_error(); }
void write_dma(Genode::size_t, Genode::size_t, Genode::addr_t) {
throw Io_error(); }
bool dma_enabled() { return false; }
Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t size) {
return Genode::env()->ram_session()->alloc(size, false); }
void sync() {}
}; };
@ -118,8 +97,7 @@ struct Factory : Block::Driver_factory
PINF("Using file=%s as device with block size %zx.", file, blk_sz); PINF("Using file=%s as device with block size %zx.", file, blk_sz);
try { try {
Rom_blk *driver = new (Genode::env()->heap()) Rom_blk(file, blk_sz); return new (Genode::env()->heap()) Rom_blk(file, blk_sz);
return driver;
} catch(Rom_connection::Rom_connection_failed) { } catch(Rom_connection::Rom_connection_failed) {
PERR("Cannot open file %s.", file); PERR("Cannot open file %s.", file);
} }

View File

@ -60,7 +60,8 @@ class Driver : public Block::Driver
void read(Genode::size_t block_number, void read(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char *buffer) char *buffer,
Block::Packet_descriptor &packet)
{ {
/* sanity check block number */ /* sanity check block number */
if (block_number + block_count > _fb_size / BLOCK_SIZE) { if (block_number + block_count > _fb_size / BLOCK_SIZE) {
@ -73,11 +74,13 @@ class Driver : public Block::Driver
Genode::size_t size = block_count * BLOCK_SIZE; Genode::size_t size = block_count * BLOCK_SIZE;
Genode::memcpy((void*)buffer, (void*)(_fb_addr + offset), size); Genode::memcpy((void*)buffer, (void*)(_fb_addr + offset), size);
session->complete_packet(packet);
} }
void write(Genode::size_t block_number, void write(Genode::size_t block_number,
Genode::size_t block_count, Genode::size_t block_count,
char const *buffer) char const *buffer,
Block::Packet_descriptor &packet)
{ {
/* sanity check block number */ /* sanity check block number */
if (block_number + block_count > _fb_size / BLOCK_SIZE) { if (block_number + block_count > _fb_size / BLOCK_SIZE) {
@ -91,20 +94,8 @@ class Driver : public Block::Driver
Genode::memcpy((void*)(_fb_addr + offset), (void*)buffer, size); Genode::memcpy((void*)(_fb_addr + offset), (void*)buffer, size);
_fb.refresh(0, 0, _fb_mode.width(), _fb_mode.height()); _fb.refresh(0, 0, _fb_mode.width(), _fb_mode.height());
session->complete_packet(packet);
} }
void read_dma(Genode::size_t block_number,
Genode::size_t block_count,
Genode::addr_t phys) {
throw Io_error(); }
void write_dma(Genode::size_t block_number,
Genode::size_t block_count,
Genode::addr_t phys) {
throw Io_error(); }
bool dma_enabled() { return false; }
Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t size) {
return Genode::env()->ram_session()->alloc(size, false); }
void sync() {}
}; };