Generalize the EndpointServer to require less boilerplate.

Classes can now inherit from the EndpointServer and just implement the
HandleRequest function.
This commit is contained in:
Drew Galbraith 2023-08-01 15:52:08 -07:00
parent 847d37addc
commit caccb08e16
14 changed files with 215 additions and 147 deletions

View file

@ -7,61 +7,57 @@
namespace {
DenaliServer* gServer = nullptr;
void HandleResponse(z_cap_t reply_port, uint64_t lba, uint64_t size,
void HandleResponse(ResponseContext& response, uint64_t lba, uint64_t size,
z_cap_t mem) {
gServer->HandleResponse(reply_port, lba, size, mem);
gServer->HandleResponse(response, lba, size, mem);
}
} // namespace
DenaliServer::DenaliServer(glcr::UniquePtr<EndpointServer> server,
AhciDriver& driver)
: server_(glcr::Move(server)), driver_(driver) {
gServer = this;
glcr::ErrorOr<glcr::UniquePtr<DenaliServer>> DenaliServer::Create(
AhciDriver& driver) {
z_cap_t cap;
RET_ERR(ZEndpointCreate(&cap));
return glcr::UniquePtr<DenaliServer>(new DenaliServer(cap, driver));
}
glcr::ErrorCode DenaliServer::RunServer() {
while (true) {
uint64_t buff_size = kBuffSize;
z_cap_t reply_port;
RET_ERR(server_->Recieve(&buff_size, read_buffer_, &reply_port));
if (buff_size < sizeof(uint64_t)) {
dbgln("Skipping invalid message");
continue;
}
uint64_t type = *reinterpret_cast<uint64_t*>(read_buffer_);
switch (type) {
case Z_INVALID:
dbgln(reinterpret_cast<char*>(read_buffer_));
break;
case DENALI_READ: {
DenaliRead* read_req = reinterpret_cast<DenaliRead*>(read_buffer_);
uint64_t memcap = 0;
RET_ERR(HandleRead(*read_req, reply_port));
break;
glcr::ErrorCode DenaliServer::HandleRequest(RequestContext& request,
ResponseContext& response) {
switch (request.request_id()) {
case DENALI_READ: {
DenaliReadRequest* req = 0;
glcr::ErrorCode err = request.As<DenaliReadRequest>(&req);
if (err != glcr::OK) {
response.WriteError(err);
}
default:
dbgln("Invalid message type.");
return glcr::UNIMPLEMENTED;
err = HandleRead(req, response);
if (err != glcr::OK) {
response.WriteError(err);
}
break;
}
default:
response.WriteError(glcr::UNIMPLEMENTED);
break;
}
return glcr::OK;
}
glcr::ErrorCode DenaliServer::HandleRead(const DenaliRead& read,
z_cap_t reply_port) {
ASSIGN_OR_RETURN(AhciDevice * device, driver_.GetDevice(read.device_id));
glcr::ErrorCode DenaliServer::HandleRead(DenaliReadRequest* request,
ResponseContext& context) {
ASSIGN_OR_RETURN(AhciDevice * device, driver_.GetDevice(request->device_id));
device->IssueCommand(
new DmaReadCommand(read.lba, read.size, ::HandleResponse, reply_port));
device->IssueCommand(new DmaReadCommand(request->lba, request->size,
::HandleResponse, context));
return glcr::OK;
}
void DenaliServer::HandleResponse(z_cap_t reply_port, uint64_t lba,
void DenaliServer::HandleResponse(ResponseContext& response, uint64_t lba,
uint64_t size, z_cap_t mem) {
DenaliReadResponse resp{
.device_id = 0,
.lba = lba,
.size = size,
};
check(ZReplyPortSend(reply_port, sizeof(resp), &resp, 1, &mem));
check(response.WriteStructWithCap<DenaliReadResponse>(resp, mem));
}