mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 20:42:56 +01:00
committed by
Norman Feske
parent
9c698ab6c1
commit
c3c643bcf1
@@ -30,6 +30,21 @@ namespace Block {
|
||||
|
||||
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:
|
||||
|
||||
Driver_factory &_driver_factory;
|
||||
@@ -60,40 +75,34 @@ class Block::Session_component : public Block::Session_rpc_object
|
||||
if (_driver.dma_enabled())
|
||||
_driver.read_dma(packet.block_number(),
|
||||
packet.block_count(),
|
||||
_rq_phys + packet.offset());
|
||||
_rq_phys + packet.offset(),
|
||||
packet);
|
||||
else
|
||||
_driver.read(packet.block_number(),
|
||||
packet.block_count(),
|
||||
tx_sink()->packet_content(packet));
|
||||
tx_sink()->packet_content(packet),
|
||||
packet);
|
||||
break;
|
||||
|
||||
case Block::Packet_descriptor::WRITE:
|
||||
if (_driver.dma_enabled())
|
||||
_driver.write_dma(packet.block_number(),
|
||||
packet.block_count(),
|
||||
_rq_phys + packet.offset());
|
||||
_rq_phys + packet.offset(),
|
||||
packet);
|
||||
else
|
||||
_driver.write(packet.block_number(),
|
||||
packet.block_count(),
|
||||
tx_sink()->packet_content(packet));
|
||||
tx_sink()->packet_content(packet),
|
||||
packet);
|
||||
break;
|
||||
|
||||
default:
|
||||
PWRN("received invalid packet");
|
||||
packet.succeeded(false);
|
||||
continue;
|
||||
throw 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_packet_avail(_sink_submit);
|
||||
|
||||
driver.session = this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* \brief Block-driver interface
|
||||
* \author Christian Helmuth
|
||||
* \author Sebastian Sumpf
|
||||
* \author Stefan kalkowski
|
||||
* \date 2011-05-23
|
||||
*/
|
||||
|
||||
@@ -17,115 +18,132 @@
|
||||
|
||||
#include <base/exception.h>
|
||||
#include <base/stdint.h>
|
||||
#include <base/signal.h>
|
||||
|
||||
#include <ram_session/ram_session.h>
|
||||
#include <block_session/block_session.h>
|
||||
|
||||
namespace Block {
|
||||
class Session_component;
|
||||
struct Driver;
|
||||
struct Driver_factory;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Interface to be implemented by the device-specific driver code
|
||||
*/
|
||||
struct Block::Driver
|
||||
{
|
||||
Session_component *session;
|
||||
|
||||
/**
|
||||
* Interface to be implemented by the device-specific driver code
|
||||
* Exceptions
|
||||
*/
|
||||
struct Driver
|
||||
{
|
||||
/**
|
||||
* Exceptions
|
||||
*/
|
||||
class Io_error : public ::Genode::Exception { };
|
||||
|
||||
/**
|
||||
* Request block size for driver and medium
|
||||
*/
|
||||
virtual Genode::size_t block_size() = 0;
|
||||
|
||||
/**
|
||||
* Request capacity of medium in blocks
|
||||
*/
|
||||
virtual Genode::size_t block_count() = 0;
|
||||
|
||||
/**
|
||||
* Request operations supported by the device
|
||||
*/
|
||||
virtual Session::Operations ops() = 0;
|
||||
|
||||
/**
|
||||
* Read from medium
|
||||
*
|
||||
* \param block_number number of first block to read
|
||||
* \param block_count number of blocks to read
|
||||
* \param out_buffer output buffer for read request
|
||||
*/
|
||||
virtual void read(Genode::size_t block_number,
|
||||
Genode::size_t block_count,
|
||||
char *out_buffer) = 0;
|
||||
|
||||
/**
|
||||
* Write to medium
|
||||
*
|
||||
* \param block_number number of first block to write
|
||||
* \param block_count number of blocks to write
|
||||
* \param buffer buffer for write request
|
||||
*/
|
||||
virtual void write(Genode::size_t block_number,
|
||||
Genode::size_t block_count,
|
||||
char const *buffer) = 0;
|
||||
|
||||
/**
|
||||
* Read from medium using DMA
|
||||
*
|
||||
* \param block_number number of first block to read
|
||||
* \param block_count number of blocks to read
|
||||
* \param phys phyiscal address of read buffer
|
||||
*/
|
||||
virtual void read_dma(Genode::size_t block_number,
|
||||
Genode::size_t block_count,
|
||||
Genode::addr_t phys) = 0;
|
||||
|
||||
/**
|
||||
* Write to medium using DMA
|
||||
*
|
||||
* \param block_number number of first block to write
|
||||
* \param block_count number of blocks to write
|
||||
* \param phys physical address of write buffer
|
||||
*/
|
||||
virtual void write_dma(Genode::size_t block_number,
|
||||
Genode::size_t block_count,
|
||||
Genode::addr_t phys) = 0;
|
||||
|
||||
/**
|
||||
* Check if DMA is enabled for driver
|
||||
*
|
||||
* \return true if DMA is enabled, false otherwise
|
||||
*/
|
||||
virtual bool dma_enabled() = 0;
|
||||
|
||||
/**
|
||||
* Allocate buffer which is suitable for DMA.
|
||||
*/
|
||||
virtual Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t) = 0;
|
||||
|
||||
/**
|
||||
* Synchronize with with device.
|
||||
*/
|
||||
virtual void sync() = 0;
|
||||
};
|
||||
|
||||
class Io_error : public ::Genode::Exception { };
|
||||
|
||||
/**
|
||||
* Interface for constructing the driver object
|
||||
* Request block size for driver and medium
|
||||
*/
|
||||
struct Driver_factory
|
||||
{
|
||||
/**
|
||||
* Construct new driver
|
||||
*/
|
||||
virtual Driver *create() = 0;
|
||||
virtual Genode::size_t block_size() = 0;
|
||||
|
||||
/**
|
||||
* Destroy driver
|
||||
*/
|
||||
virtual void destroy(Driver *driver) = 0;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Request capacity of medium in blocks
|
||||
*/
|
||||
virtual Genode::size_t block_count() = 0;
|
||||
|
||||
/**
|
||||
* Request operations supported by the device
|
||||
*/
|
||||
virtual Session::Operations ops() = 0;
|
||||
|
||||
/**
|
||||
* Read from medium
|
||||
*
|
||||
* \param block_number number of first block to read
|
||||
* \param block_count number of blocks to read
|
||||
* \param buffer output buffer for read request
|
||||
*/
|
||||
virtual void read(Genode::size_t block_number,
|
||||
Genode::size_t block_count,
|
||||
char * buffer,
|
||||
Packet_descriptor &packet) {
|
||||
throw Io_error(); }
|
||||
|
||||
/**
|
||||
* Write to medium
|
||||
*
|
||||
* \param block_number number of first block to write
|
||||
* \param block_count number of blocks to write
|
||||
* \param buffer buffer for write request
|
||||
*/
|
||||
virtual void write(Genode::size_t block_number,
|
||||
Genode::size_t block_count,
|
||||
const char * buffer,
|
||||
Packet_descriptor &packet) {
|
||||
throw Io_error(); }
|
||||
|
||||
/**
|
||||
* Read from medium using DMA
|
||||
*
|
||||
* \param block_number number of first block to read
|
||||
* \param block_count number of blocks to read
|
||||
* \param phys phyiscal address of read buffer
|
||||
*/
|
||||
virtual void read_dma(Genode::size_t block_number,
|
||||
Genode::size_t block_count,
|
||||
Genode::addr_t phys,
|
||||
Packet_descriptor &packet) {
|
||||
throw Io_error(); }
|
||||
|
||||
/**
|
||||
* Write to medium using DMA
|
||||
*
|
||||
* \param block_number number of first block to write
|
||||
* \param block_count number of blocks to write
|
||||
* \param phys physical address of write buffer
|
||||
*/
|
||||
virtual void write_dma(Genode::size_t block_number,
|
||||
Genode::size_t block_count,
|
||||
Genode::addr_t phys,
|
||||
Packet_descriptor &packet) {
|
||||
throw Io_error(); }
|
||||
|
||||
/**
|
||||
* Check if DMA is enabled for driver
|
||||
*
|
||||
* \return true if DMA is enabled, false otherwise
|
||||
*/
|
||||
virtual bool dma_enabled() { return false; }
|
||||
|
||||
/**
|
||||
* Allocate buffer which is suitable for DMA.
|
||||
*/
|
||||
virtual Genode::Ram_dataspace_capability
|
||||
alloc_dma_buffer(Genode::size_t size) {
|
||||
return Genode::env()->ram_session()->alloc(size, false); }
|
||||
|
||||
/**
|
||||
* Synchronize with with device.
|
||||
*/
|
||||
virtual void sync() {}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Interface for constructing the driver object
|
||||
*/
|
||||
struct Block::Driver_factory
|
||||
{
|
||||
/**
|
||||
* Construct new driver
|
||||
*/
|
||||
virtual Driver *create() = 0;
|
||||
|
||||
/**
|
||||
* Destroy driver
|
||||
*/
|
||||
virtual void destroy(Driver *driver) = 0;
|
||||
};
|
||||
|
||||
#endif /* _BLOCK__DRIVER_H_ */
|
||||
|
||||
Reference in New Issue
Block a user