blob: f7b05edef9903eb8db7377a474a7ea286d5536b8 [file] [log] [blame]
// Copyright 2019 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 <vector>
#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/platform-defs.h>
#include <ddktl/device.h>
#include <fbl/alloc_checker.h>
#include <fuchsia/device/manager/test/c/fidl.h>
class IsolatedDevMgrTestDriver;
using DeviceType = ddk::Device<IsolatedDevMgrTestDriver, ddk::Unbindable, ddk::Messageable>;
class IsolatedDevMgrTestDriver : public DeviceType {
public:
IsolatedDevMgrTestDriver(zx_device_t* parent)
: DeviceType(parent) {}
zx_status_t Bind();
void DdkUnbind() {
DdkRemove();
}
void DdkRelease() {
delete this;
}
zx_status_t DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn);
private:
static zx_status_t FidlGetMetadata(void* ctx, uint32_t type, fidl_txn_t* txn);
};
zx_status_t IsolatedDevMgrTestDriver::FidlGetMetadata(void* ctx, uint32_t type, fidl_txn_t* txn) {
IsolatedDevMgrTestDriver* driver = reinterpret_cast<IsolatedDevMgrTestDriver*>(ctx);
size_t size;
zx_status_t status = driver->DdkGetMetadataSize(type, &size);
if (status != ZX_OK) {
return status;
}
std::vector<uint8_t> metadata;
metadata.resize(size);
status = driver->DdkGetMetadata(type, metadata.data(), metadata.size(), &size);
if (status != ZX_OK) {
return status;
}
if (size != metadata.size()) {
return ZX_ERR_INTERNAL;
}
return fuchsia_device_manager_test_MetadataGetMetadata_reply(txn, metadata.data(),
metadata.size());
}
zx_status_t IsolatedDevMgrTestDriver::DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn) {
static const fuchsia_device_manager_test_Metadata_ops_t kOps = {
.GetMetadata = IsolatedDevMgrTestDriver::FidlGetMetadata,
};
return fuchsia_device_manager_test_Metadata_dispatch(this, txn, msg, &kOps);
}
zx_status_t IsolatedDevMgrTestDriver::Bind() {
return DdkAdd("metadata-test");
}
zx_status_t isolateddevmgr_test_bind(void* ctx, zx_device_t* device) {
fbl::AllocChecker ac;
auto dev = fbl::make_unique_checked<IsolatedDevMgrTestDriver>(&ac, device);
if (!ac.check()) {
return ZX_ERR_NO_MEMORY;
}
auto status = dev->Bind();
if (status == ZX_OK) {
// devmgr is now in charge of the memory for dev
__UNUSED auto ptr = dev.release();
}
return status;
}
static constexpr zx_driver_ops_t isolateddevmgr_test_driver_ops = []() -> zx_driver_ops_t {
zx_driver_ops_t ops = {};
ops.version = DRIVER_OPS_VERSION;
ops.bind = isolateddevmgr_test_bind;
return ops;
}();
// clang-format off
ZIRCON_DRIVER_BEGIN(metadataTest, isolateddevmgr_test_driver_ops, "zircon", "0.1", 4)
BI_ABORT_IF(NE, BIND_PLATFORM_DEV_VID, PDEV_VID_TEST),
BI_ABORT_IF(NE, BIND_PLATFORM_DEV_PID, PDEV_PID_METADATA_TEST),
BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_TEST_CHILD_1),
BI_MATCH_IF(EQ, BIND_PLATFORM_DEV_DID, PDEV_DID_TEST_CHILD_2),
ZIRCON_DRIVER_END(metadataTest)
// clang-format on