From acfaf2639120124a9b2bcf1a4598ff8cd50d3053 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Wed, 25 Oct 2023 19:39:09 -0700 Subject: [PATCH] [Denali] Use mutexes to synchronize the AHCI responses. This is a temporary solution to allow denali to migrate to the yunq framework until we have a good async solution. --- sys/denali/ahci/command.cpp | 8 +++----- sys/denali/ahci/command.h | 8 +++++--- sys/denali/denali_server.cpp | 31 ++++++++++++------------------- sys/denali/denali_server.h | 3 --- 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/sys/denali/ahci/command.cpp b/sys/denali/ahci/command.cpp index 986ca6d..c79a068 100644 --- a/sys/denali/ahci/command.cpp +++ b/sys/denali/ahci/command.cpp @@ -7,11 +7,11 @@ Command::~Command() {} DmaReadCommand::DmaReadCommand(uint64_t lba, uint64_t sector_cnt, - DmaCallback callback, ResponseContext& response) + Mutex& callback_mutex, ResponseContext& response) : response_(response), lba_(lba), sector_cnt_(sector_cnt), - callback_(callback) { + callback_mutex_(callback_mutex) { region_ = MappedMemoryRegion::ContiguousPhysical(sector_cnt * 512); } @@ -49,6 +49,4 @@ void DmaReadCommand::PopulatePrdt(PhysicalRegionDescriptor* prdt) { prdt[0].region_address = region_.paddr(); prdt[0].byte_count = region_.size(); } -void DmaReadCommand::Callback() { - callback_(response_, lba_, sector_cnt_, region_.cap()); -} +void DmaReadCommand::Callback() { callback_mutex_.Release(); } diff --git a/sys/denali/ahci/command.h b/sys/denali/ahci/command.h index 9870685..5464369 100644 --- a/sys/denali/ahci/command.h +++ b/sys/denali/ahci/command.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -16,8 +17,7 @@ class Command { class DmaReadCommand : public Command { public: - typedef void (*DmaCallback)(ResponseContext&, uint64_t, uint64_t, z_cap_t); - DmaReadCommand(uint64_t lba, uint64_t sector_cnt, DmaCallback callback, + DmaReadCommand(uint64_t lba, uint64_t sector_cnt, Mutex& callback_mutex_, ResponseContext& reply_port); virtual ~DmaReadCommand() override; @@ -27,10 +27,12 @@ class DmaReadCommand : public Command { void Callback() override; + z_cap_t GetMemoryRegion() { return region_.cap(); } + private: ResponseContext& response_; uint64_t lba_; uint64_t sector_cnt_; - DmaCallback callback_; + Mutex& callback_mutex_; MappedMemoryRegion region_; }; diff --git a/sys/denali/denali_server.cpp b/sys/denali/denali_server.cpp index caa29a4..a4e9767 100644 --- a/sys/denali/denali_server.cpp +++ b/sys/denali/denali_server.cpp @@ -5,14 +5,6 @@ #include #include -namespace { -DenaliServer* gServer = nullptr; -void HandleResponse(ResponseContext& response, uint64_t lba, uint64_t size, - z_cap_t mem) { - gServer->HandleResponse(response, lba, size, mem); -} -} // namespace - glcr::ErrorOr> DenaliServer::Create( AhciDriver& driver) { z_cap_t cap; @@ -45,19 +37,20 @@ glcr::ErrorCode DenaliServer::HandleRequest(RequestContext& request, glcr::ErrorCode DenaliServer::HandleRead(DenaliReadRequest* request, ResponseContext& context) { ASSIGN_OR_RETURN(AhciDevice * device, driver_.GetDevice(request->device_id)); + ASSIGN_OR_RETURN(Mutex mutex, Mutex::Create()); + RET_ERR(mutex.Lock()); - device->IssueCommand(new DmaReadCommand(request->lba, request->size, - ::HandleResponse, context)); + DmaReadCommand command(request->lba, request->size, mutex, context); + device->IssueCommand(&command); - return glcr::OK; -} - -void DenaliServer::HandleResponse(ResponseContext& response, uint64_t lba, - uint64_t size, z_cap_t mem) { + // Wait for read operation to complete. + RET_ERR(mutex.Lock()); + RET_ERR(mutex.Release()); DenaliReadResponse resp{ - .device_id = 0, - .lba = lba, - .size = size, + .device_id = request->device_id, + .lba = request->lba, + .size = request->size, }; - check(response.WriteStructWithCap(resp, mem)); + return context.WriteStructWithCap( + resp, command.GetMemoryRegion()); } diff --git a/sys/denali/denali_server.h b/sys/denali/denali_server.h index 677185d..82c6a85 100644 --- a/sys/denali/denali_server.h +++ b/sys/denali/denali_server.h @@ -11,9 +11,6 @@ class DenaliServer : public EndpointServer { static glcr::ErrorOr> Create( AhciDriver& driver); - void HandleResponse(ResponseContext& response, uint64_t lba, uint64_t size, - z_cap_t cap); - virtual glcr::ErrorCode HandleRequest(RequestContext& request, ResponseContext& response) override;