parent
9c698ab6c1
commit
c3c643bcf1
|
@ -39,9 +39,8 @@ class Driver : public Block::Driver
|
||||||
** Block::Driver interface **
|
** Block::Driver interface **
|
||||||
*******************************/
|
*******************************/
|
||||||
|
|
||||||
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()
|
||||||
{
|
{
|
||||||
|
@ -50,25 +49,15 @@ class Driver : public Block::Driver
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,8 +81,8 @@ class Factory : public Block::Driver_factory
|
||||||
PINF("Using file=%s as device with block size %zx.", _uri, _blk_sz);
|
PINF("Using file=%s as device with block size %zx.", _uri, _blk_sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
Block::Driver *create() {
|
Block::Driver *create() {
|
||||||
return new (env()->heap()) Driver(_blk_sz, _uri); }
|
return new (env()->heap()) Driver(_blk_sz, _uri); }
|
||||||
|
|
||||||
void destroy(Block::Driver *driver) {
|
void destroy(Block::Driver *driver) {
|
||||||
Genode::destroy(env()->heap(), driver); }
|
Genode::destroy(env()->heap(), driver); }
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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,115 +18,132 @@
|
||||||
|
|
||||||
#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
|
||||||
|
*/
|
||||||
|
struct Block::Driver
|
||||||
|
{
|
||||||
|
Session_component *session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to be implemented by the device-specific driver code
|
* Exceptions
|
||||||
*/
|
*/
|
||||||
struct Driver
|
class Io_error : public ::Genode::Exception { };
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for constructing the driver object
|
* Request block size for driver and medium
|
||||||
*/
|
*/
|
||||||
struct Driver_factory
|
virtual Genode::size_t block_size() = 0;
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Construct new driver
|
|
||||||
*/
|
|
||||||
virtual Driver *create() = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy driver
|
* Request capacity of medium in blocks
|
||||||
*/
|
*/
|
||||||
virtual void destroy(Driver *driver) = 0;
|
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_ */
|
#endif /* _BLOCK__DRIVER_H_ */
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
@ -55,40 +56,30 @@ class Ahci_driver_base : public Block::Driver
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dma_enabled() { return true; }
|
bool dma_enabled() { return true; }
|
||||||
|
|
||||||
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_ */
|
||||||
|
|
|
@ -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() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -97,44 +97,47 @@ class Block::Exynos5_driver : public Block::Driver
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
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_ */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -90,44 +90,47 @@ class Block::Omap4_driver : public Block::Driver
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
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_ */
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
|
@ -57,9 +57,10 @@ class Rom_blk : public Block::Driver
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,9 +58,10 @@ class Driver : public Block::Driver
|
||||||
return ops;
|
return ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
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,26 +94,14 @@ 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() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Factory : Block::Driver_factory
|
struct Factory : Block::Driver_factory
|
||||||
{
|
{
|
||||||
Block::Driver *create() {
|
Block::Driver *create() {
|
||||||
return new (Genode::env()->heap()) Driver(); }
|
return new (Genode::env()->heap()) Driver(); }
|
||||||
|
|
||||||
void destroy(Block::Driver *driver) {
|
void destroy(Block::Driver *driver) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user