blob: 351bfe82049e047876155ffd973473928add4890 [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 "test-driver-child.h"
#include <ddk/debug.h>
#include <ddktl/device.h>
#include <fbl/alloc_checker.h>
#include <fbl/ref_counted.h>
#include <fbl/ref_ptr.h>
using llcpp::fuchsia::device::instancelifecycle::test::Lifecycle;
void TestLifecycleDriverChild::DdkRelease() {
zx_status_t status = Lifecycle::SendOnReleaseEvent(zx::unowned(lifecycle_));
ZX_ASSERT(status == ZX_OK);
delete this;
}
zx_status_t TestLifecycleDriverChild::Create(zx_device_t* parent, zx::channel lifecycle_client,
zx::channel instance_client) {
auto device = std::make_unique<TestLifecycleDriverChild>(parent, std::move(lifecycle_client));
zx_status_t status = device->DdkAdd("child", /* flags */ 0, /* props */ nullptr,
/* prop_count */ 0, /* proto_id */ 0,
/* proxy_args */ nullptr, instance_client.release());
if (status == ZX_OK) {
// devmgr is now in charge of the memory for dev
__UNUSED auto ptr = device.release();
}
return status;
}
void TestLifecycleDriverChild::DdkUnbindNew(ddk::UnbindTxn txn) {
zx_status_t status = Lifecycle::SendOnUnbindEvent(zx::unowned(lifecycle_));
ZX_ASSERT(status == ZX_OK);
txn.Reply();
}
zx_status_t TestLifecycleDriverChild::DdkOpen(zx_device_t** out, uint32_t flags) {
zx_status_t status = Lifecycle::SendOnOpenEvent(zx::unowned(lifecycle_));
ZX_ASSERT(status == ZX_OK);
auto device = std::make_unique<TestLifecycleDriverChildInstance>(zxdev(), this);
status = device->DdkAdd("child-instance", DEVICE_ADD_INSTANCE);
if (status != ZX_OK) {
return status;
}
*out = device->zxdev();
// devmgr is now in charge of the memory for dev
__UNUSED auto ptr = device.release();
return ZX_OK;
}
// Implementation of the instance devices
zx_status_t TestLifecycleDriverChildInstance::DdkClose(uint32_t flags) {
if (lifecycle_) {
zx_status_t status = Lifecycle::SendOnCloseEvent(zx::unowned(lifecycle_));
ZX_ASSERT(status == ZX_OK);
}
return ZX_OK;
}
void TestLifecycleDriverChildInstance::DdkRelease() {
if (lifecycle_) {
zx_status_t status = Lifecycle::SendOnReleaseEvent(zx::unowned(lifecycle_));
ZX_ASSERT(status == ZX_OK);
}
delete this;
}
void TestLifecycleDriverChildInstance::RemoveDevice(RemoveDeviceCompleter::Sync completer) {
parent_ctx_->DdkAsyncRemove();
}
void TestLifecycleDriverChildInstance::SubscribeToLifecycle(
zx::channel client, SubscribeToLifecycleCompleter::Sync completer) {
// Currently we only care about supporting one client.
if (lifecycle_) {
completer.ReplyError(ZX_ERR_ALREADY_BOUND);
} else {
lifecycle_ = std::move(client);
completer.ReplySuccess();
}
}