mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-09 04:15:52 +00:00
ahci: add sync operation support
- implemement 'flush cache ext' for ATA - enable sync operation for request stream issue #3636
This commit is contained in:
parent
e096202b1f
commit
5225d12381
@ -250,6 +250,13 @@ namespace Ahci {
|
||||
write<Sector0_7::Tag>(slot);
|
||||
}
|
||||
|
||||
void flush_cache_ext()
|
||||
{
|
||||
write<Bits::C>(1);
|
||||
write<Device::Lba>(0);
|
||||
write<Command>(0xea);
|
||||
}
|
||||
|
||||
void atapi()
|
||||
{
|
||||
write<Bits::C>(1);
|
||||
|
@ -171,10 +171,14 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable
|
||||
(pending_start >= block_number && pending_start <= end) ||
|
||||
(pending_end >= block_number && pending_end <= end)) {
|
||||
|
||||
warning("overlap: "
|
||||
warning("overlap: ",
|
||||
"pending ", pending_start,
|
||||
" + ", req.operation.count, ", "
|
||||
"request: ", block_number, " + ", request.operation.count);
|
||||
" + ", req.operation.count,
|
||||
" (", req.operation.type == Block::Operation::Type::WRITE ?
|
||||
"write" : "read", "), ",
|
||||
"request: ", block_number, " + ", request.operation.count,
|
||||
" (", request.operation.type == Block::Operation::Type::WRITE ?
|
||||
"write" : "read", ")");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -248,10 +252,14 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable
|
||||
|
||||
void handle_irq(Port &port) override
|
||||
{
|
||||
unsigned is = port.read<Port::Is>();
|
||||
|
||||
/* ncg */
|
||||
if (_ncq_support(port))
|
||||
while (Port::Is::Sdbs::get(port.read<Port::Is>()))
|
||||
if (_ncq_support(port) && Port::Is::Fpdma_irq::get(is))
|
||||
do {
|
||||
port.ack_irq();
|
||||
}
|
||||
while (Port::Is::Sdbs::get(port.read<Port::Is>()));
|
||||
/* normal dma */
|
||||
else if (Port::Is::Dma_ext_irq::get(port.read<Port::Is>()))
|
||||
port.ack_irq();
|
||||
@ -272,14 +280,16 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable
|
||||
|
||||
Response submit(Port &port, Block::Request const request) override
|
||||
{
|
||||
if (port.sanity_check(request) == false || port.dma_base == 0)
|
||||
return Response::REJECTED;
|
||||
|
||||
if (_writeable == false && request.operation.type == Block::Operation::Type::WRITE)
|
||||
return Response::REJECTED;
|
||||
|
||||
if (_overlap_check(request))
|
||||
return Response::RETRY;
|
||||
if (Block::Operation::has_payload(request.operation.type)) {
|
||||
if (port.sanity_check(request) == false || port.dma_base == 0)
|
||||
return Response::REJECTED;
|
||||
|
||||
if (_overlap_check(request))
|
||||
return Response::RETRY;
|
||||
}
|
||||
|
||||
Request *r = _slots.get();
|
||||
|
||||
@ -298,21 +308,26 @@ class Ata::Protocol : public Ahci::Protocol, Noncopyable
|
||||
op.count * _block_size());
|
||||
|
||||
/* setup ATA command */
|
||||
bool read = op.type == Block::Operation::Type::READ;
|
||||
|
||||
if (_ncq_support(port)) {
|
||||
table.fis.fpdma(read, op.block_number, op.count, slot);
|
||||
/* write bit for command header + read/write ATA requests */
|
||||
bool const write = (op.type == Block::Operation::Type::WRITE);
|
||||
bool const sync = (op.type == Block::Operation::Type::SYNC);
|
||||
|
||||
if (sync) {
|
||||
table.fis.flush_cache_ext();
|
||||
} else if (_ncq_support(port)) {
|
||||
table.fis.fpdma(write == false, op.block_number, op.count, slot);
|
||||
/* ensure that 'Cmd::St' is 1 before writing 'Sact' */
|
||||
port.start();
|
||||
/* set pending */
|
||||
port.write<Port::Sact>(1U << slot);
|
||||
} else {
|
||||
table.fis.dma_ext(read, op.block_number, op.count);
|
||||
table.fis.dma_ext(write == false, op.block_number, op.count);
|
||||
}
|
||||
|
||||
/* set or clear write flag in command header */
|
||||
Command_header header(port.command_header_addr(slot));
|
||||
header.write<Command_header::Bits::W>(read ? 0 : 1);
|
||||
header.write<Command_header::Bits::W>(write ? 1 : 0);
|
||||
header.clear_byte_count();
|
||||
|
||||
port.execute(slot);
|
||||
|
@ -148,8 +148,8 @@ class Atapi::Protocol : public Ahci::Protocol, Noncopyable
|
||||
|
||||
Response submit(Port &port, Block::Request const request) override
|
||||
{
|
||||
if (port.sanity_check(request) == false || port.dma_base == 0 ||
|
||||
request.operation.type != Block::Operation::Type::READ)
|
||||
if (request.operation.type != Block::Operation::Type::READ ||
|
||||
port.sanity_check(request) == false || port.dma_base == 0)
|
||||
return Response::REJECTED;
|
||||
|
||||
if (_pending.operation.valid())
|
||||
|
@ -275,8 +275,9 @@ struct Ahci::Block_session_component : Rpc_object<Block::Session>,
|
||||
|
||||
Response response = Response::RETRY;
|
||||
|
||||
/* only READ/WRITE requests, others are noops for now */
|
||||
if (Block::Operation::has_payload(request.operation.type) == false) {
|
||||
/* ignored operations */
|
||||
if (request.operation.type == Block::Operation::Type::TRIM ||
|
||||
request.operation.type == Block::Operation::Type::INVALID) {
|
||||
request.success = true;
|
||||
progress = true;
|
||||
return Response::REJECTED;
|
||||
|
Loading…
x
Reference in New Issue
Block a user