diff --git a/repos/os/src/drivers/ahci/ahci.h b/repos/os/src/drivers/ahci/ahci.h index 31b87541a..123367fb5 100644 --- a/repos/os/src/drivers/ahci/ahci.h +++ b/repos/os/src/drivers/ahci/ahci.h @@ -250,6 +250,13 @@ namespace Ahci { write(slot); } + void flush_cache_ext() + { + write(1); + write(0); + write(0xea); + } + void atapi() { write(1); diff --git a/repos/os/src/drivers/ahci/ata_protocol.h b/repos/os/src/drivers/ahci/ata_protocol.h index d3c53ca88..adecb5537 100644 --- a/repos/os/src/drivers/ahci/ata_protocol.h +++ b/repos/os/src/drivers/ahci/ata_protocol.h @@ -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(); + /* ncg */ - if (_ncq_support(port)) - while (Port::Is::Sdbs::get(port.read())) + if (_ncq_support(port) && Port::Is::Fpdma_irq::get(is)) + do { port.ack_irq(); + } + while (Port::Is::Sdbs::get(port.read())); /* normal dma */ else if (Port::Is::Dma_ext_irq::get(port.read())) 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(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(read ? 0 : 1); + header.write(write ? 1 : 0); header.clear_byte_count(); port.execute(slot); diff --git a/repos/os/src/drivers/ahci/atapi_protocol.h b/repos/os/src/drivers/ahci/atapi_protocol.h index d552cfeb3..d39693e33 100644 --- a/repos/os/src/drivers/ahci/atapi_protocol.h +++ b/repos/os/src/drivers/ahci/atapi_protocol.h @@ -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()) diff --git a/repos/os/src/drivers/ahci/main.cc b/repos/os/src/drivers/ahci/main.cc index 9b1192c02..9f184c5c9 100644 --- a/repos/os/src/drivers/ahci/main.cc +++ b/repos/os/src/drivers/ahci/main.cc @@ -275,8 +275,9 @@ struct Ahci::Block_session_component : Rpc_object, 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;