blob: 2f30baa9afd0ba20ec6e12f086b1846668bf1e48 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "platform-proxy-client.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>
#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <fbl/algorithm.h>
#include <fbl/unique_ptr.h>
#include "platform-proxy.h"
namespace platform_bus {
zx_status_t ProxyClient::Create(uint32_t proto_id, zx_device_t* parent,
fbl::RefPtr<PlatformProxy> proxy) {
fbl::AllocChecker ac;
auto client = fbl::make_unique_checked<ProxyClient>(&ac, proto_id, parent, proxy);
if (!ac.check()) {
return ZX_ERR_NO_MEMORY;
}
char name[ZX_DEVICE_NAME_MAX];
snprintf(name, sizeof(name), "ProxyClient[%08x]", proto_id);
zx_device_prop_t props[] = {
{BIND_PLATFORM_PROTO, 0, proto_id},
};
auto status = client->DdkAdd(name, 0, props, fbl::count_of(props));
if (status != ZX_OK) {
return status;
}
// devmgr is now in charge of the device.
__UNUSED auto* dummy = client.release();
return ZX_OK;
}
void ProxyClient::DdkRelease() {
proxy_->UnregisterProtocol(proto_id_);
delete this;
}
zx_status_t ProxyClient::PlatformProxyRegisterProtocol(uint32_t proto_id, const void* protocol,
size_t protocol_size) {
if (proto_id != proto_id_) {
// We may allow drivers to implement multiple protocols in the future,
// but for now require that the driver only proxy the one protocol we loaded it for.
return ZX_ERR_ACCESS_DENIED;
}
return proxy_->RegisterProtocol(proto_id, protocol);
}
zx_status_t ProxyClient::PlatformProxyProxy(
const void* req_buffer, size_t req_size, const zx_handle_t* req_handle_list,
size_t req_handle_count, void* out_resp_buffer, size_t resp_size, size_t* out_resp_actual,
zx_handle_t* out_resp_handle_list, size_t resp_handle_count, size_t* out_resp_handle_actual) {
auto* req = static_cast<const platform_proxy_req*>(req_buffer);
if (req->proto_id != proto_id_) {
// We may allow drivers to implement multiple protocols in the future,
// but for now require that the driver only proxy the one protocol we loaded it for.
return ZX_ERR_ACCESS_DENIED;
}
proxy_->Proxy(req_buffer, req_size, req_handle_list, req_handle_count, out_resp_buffer,
resp_size, out_resp_actual, out_resp_handle_list, resp_handle_count,
out_resp_handle_actual);
return ZX_OK;
}
} // namespace platform_bus