Add Resume task
Change-Id: Ibdceed64189c85ded6b160997ff8309db2537c5f
diff --git a/garnet/tests/system_updater/src/lib.rs b/garnet/tests/system_updater/src/lib.rs
index 4db5028..c99b140 100644
--- a/garnet/tests/system_updater/src/lib.rs
+++ b/garnet/tests/system_updater/src/lib.rs
@@ -349,11 +349,17 @@
mut stream: fidl_fuchsia_device_manager::AdministratorRequestStream,
) -> Result<(), Error> {
while let Some(event) = stream.try_next().await? {
- let fidl_fuchsia_device_manager::AdministratorRequest::Suspend { flags, responder } =
- event;
- eprintln!("TEST: Got reboot request with flags {:?}", flags);
- *self.called.lock() += 1;
- responder.send(Status::OK.into_raw())?;
+ match event {
+ fidl_fuchsia_device_manager::AdministratorRequest::Suspend { flags, responder } => {
+ eprintln!("TEST: Got reboot request with flags {:?}", flags);
+ *self.called.lock() += 1;
+ responder.send(Status::OK.into_raw())?;
+ }
+ fidl_fuchsia_device_manager::AdministratorRequest::Resume { state, responder } => {
+ eprintln!("TEST: Got Resume request with state {:?}", state);
+ responder.send(Status::OK.into_raw())?;
+ }
+ }
}
Ok(())
diff --git a/src/devices/coordinator/BUILD.gn b/src/devices/coordinator/BUILD.gn
index 864f141..cc48108 100644
--- a/src/devices/coordinator/BUILD.gn
+++ b/src/devices/coordinator/BUILD.gn
@@ -32,6 +32,7 @@
"fidl.cc",
"main.cc",
"suspend-task.cc",
+ "resume-task.cc",
"system-instance.cc",
"system-instance.h",
"task.cc",
@@ -109,6 +110,7 @@
"env.cc",
"fdio.cc",
"fidl.cc",
+ "resume-task.cc",
"suspend-task.cc",
"system-instance.cc",
"system-instance.h",
diff --git a/src/devices/coordinator/coordinator-test.cc b/src/devices/coordinator/coordinator-test.cc
index 8715371..fd5986e 100644
--- a/src/devices/coordinator/coordinator-test.cc
+++ b/src/devices/coordinator/coordinator-test.cc
@@ -609,6 +609,60 @@
SendSuspendReply(remote, return_status);
}
+// Reads a Resume request from remote and checks that it is for the expected
+// target state, without sending a response. |SendResumeReply| can be used to send the desired
+// response.
+void CheckResumeReceived(const zx::channel& remote, SystemPowerState target_state) {
+ // Read the Resume request.
+ FIDL_ALIGNDECL uint8_t bytes[ZX_CHANNEL_MAX_MSG_BYTES];
+ zx_handle_t handles[ZX_CHANNEL_MAX_MSG_HANDLES];
+ uint32_t actual_bytes;
+ uint32_t actual_handles;
+ zx_status_t status = remote.read(0, bytes, handles, sizeof(bytes), fbl::count_of(handles),
+ &actual_bytes, &actual_handles);
+ ASSERT_OK(status);
+ ASSERT_LT(0, actual_bytes);
+ ASSERT_EQ(0, actual_handles);
+
+ // Validate the Resume request.
+ auto hdr = reinterpret_cast<fidl_message_header_t*>(bytes);
+ ASSERT_EQ(fuchsia_device_manager_DeviceControllerResumeOrdinal, hdr->ordinal);
+ status = fidl_decode(&fuchsia_device_manager_DeviceControllerResumeRequestTable, bytes,
+ actual_bytes, handles, actual_handles, nullptr);
+ ASSERT_OK(status);
+ auto req = reinterpret_cast<fuchsia_device_manager_DeviceControllerResumeRequest*>(bytes);
+ ASSERT_EQ(static_cast<SystemPowerState>(req->target_system_state), target_state);
+}
+
+// Sends a response with the given return_status. This can be used to reply to a
+// request received by |CheckResumeReceived|.
+void SendResumeReply(const zx::channel& remote, zx_status_t return_status) {
+ FIDL_ALIGNDECL uint8_t bytes[ZX_CHANNEL_MAX_MSG_BYTES];
+ zx_handle_t handles[ZX_CHANNEL_MAX_MSG_HANDLES];
+ uint32_t actual_handles;
+
+ // Write the Resume response.
+ memset(bytes, 0, sizeof(bytes));
+ auto resp = reinterpret_cast<fuchsia_device_manager_DeviceControllerResumeResponse*>(bytes);
+ resp->hdr.ordinal = fuchsia_device_manager_DeviceControllerResumeOrdinal;
+ resp->status = return_status;
+ zx_status_t status =
+ fidl_encode(&fuchsia_device_manager_DeviceControllerResumeResponseTable, bytes, sizeof(*resp),
+ handles, fbl::count_of(handles), &actual_handles, nullptr);
+ ASSERT_OK(status);
+ ASSERT_EQ(0, actual_handles);
+ status = remote.write(0, bytes, sizeof(*resp), nullptr, 0);
+ ASSERT_OK(status);
+}
+
+// Reads a Resume request from remote, checks that it is for the expected
+// target state, and then sends the given response.
+void CheckResumeReceived(const zx::channel& remote, SystemPowerState target_state,
+ zx_status_t return_status) {
+ CheckResumeReceived(remote, target_state);
+ SendResumeReply(remote, return_status);
+}
+
// Reads a CreateCompositeDevice from remote, checks expectations, and sends
// a ZX_OK response.
void CheckCreateCompositeDeviceReceived(const zx::channel& remote, const char* expected_name,
@@ -707,9 +761,7 @@
async::Loop* coordinator_loop() { return &coordinator_loop_; }
bool coordinator_loop_thread_running() { return coordinator_loop_thread_running_; }
- void set_coordinator_loop_thread_running(bool value) {
- coordinator_loop_thread_running_ = value;
- }
+ void set_coordinator_loop_thread_running(bool value) { coordinator_loop_thread_running_ = value; }
devmgr::Coordinator* coordinator() { return &coordinator_; }
devmgr::Devhost* devhost() { return &devhost_; }
@@ -729,6 +781,9 @@
void DoSuspend(uint32_t flags);
void DoSuspend(uint32_t flags, fit::function<void(uint32_t)> suspend_cb);
+ void DoResume(SystemPowerState target_state);
+ void DoResume(SystemPowerState target_state, fit::function<void(SystemPowerState)> resume_cb);
+
void CheckUnbindReceived(const zx::channel& remote);
void SendUnbindReply(const zx::channel& remote);
void CheckUnbindReceivedAndReply(const zx::channel& remote);
@@ -897,6 +952,19 @@
DoSuspend(flags, [this](uint32_t flags) { coordinator()->Suspend(flags); });
}
+void MultipleDeviceTestCase::DoResume(
+ SystemPowerState target_state, fit::function<void(SystemPowerState target_state)> resume_cb) {
+ resume_cb(target_state);
+ if (!coordinator_loop_thread_running()) {
+ coordinator_loop()->RunUntilIdle();
+ }
+}
+
+void MultipleDeviceTestCase::DoResume(SystemPowerState target_state) {
+ DoResume(target_state,
+ [this](SystemPowerState target_state) { coordinator()->Resume(target_state); });
+}
+
TEST_F(MultipleDeviceTestCase, RemoveDeadDevice) {
size_t index;
ASSERT_NO_FATAL_FAILURES(AddDevice(platform_bus(), "device", 0 /* protocol id */, "", &index));
@@ -954,8 +1022,8 @@
// Verify the UnbindDone response.
uint32_t actual_bytes;
- status = remote.read(0, bytes, handles, sizeof(bytes), fbl::count_of(handles),
- &actual_bytes, &actual_handles);
+ status = remote.read(0, bytes, handles, sizeof(bytes), fbl::count_of(handles), &actual_bytes,
+ &actual_handles);
ASSERT_OK(status);
ASSERT_LT(0, actual_bytes);
ASSERT_EQ(0, actual_handles);
@@ -1021,8 +1089,8 @@
// Verify the RemoveDone response.
uint32_t actual_bytes;
- status = remote.read(0, bytes, handles, sizeof(bytes), fbl::count_of(handles),
- &actual_bytes, &actual_handles);
+ status = remote.read(0, bytes, handles, sizeof(bytes), fbl::count_of(handles), &actual_bytes,
+ &actual_handles);
ASSERT_OK(status);
ASSERT_LT(0, actual_bytes);
ASSERT_EQ(0, actual_handles);
@@ -1536,13 +1604,13 @@
auto* child_device = device(child_index);
- ASSERT_NO_FATAL_FAILURES(coordinator_.ScheduleDevhostRequestedRemove(parent_device->device,
- false /* do_unbind */));
+ ASSERT_NO_FATAL_FAILURES(
+ coordinator_.ScheduleDevhostRequestedRemove(parent_device->device, false /* do_unbind */));
coordinator_loop()->RunUntilIdle();
// At the same time, have the child try to remove itself.
- ASSERT_NO_FATAL_FAILURES(coordinator_.ScheduleDevhostRequestedRemove(child_device->device,
- false /* do_unbind */));
+ ASSERT_NO_FATAL_FAILURES(
+ coordinator_.ScheduleDevhostRequestedRemove(child_device->device, false /* do_unbind */));
coordinator_loop()->RunUntilIdle();
// The child device will not reply, as it already called device_remove previously.
@@ -1678,6 +1746,51 @@
ASSERT_EQ(device(index)->device->state(), want_device_state);
}
+class ResumeTestCase : public MultipleDeviceTestCase {
+ public:
+ void ResumeTest(SystemPowerState target_state);
+ void StateTest(zx_status_t resume_status, devmgr::Device::State want_device_state);
+};
+
+// Verify the resume order is correct
+void ResumeTestCase::ResumeTest(SystemPowerState target_state) {
+ struct DeviceDesc {
+ // Index into the device desc array below. UINT32_MAX = platform_bus()
+ const size_t parent_desc_index;
+ const char* const name;
+ // index for use with device()
+ size_t index = 0;
+ };
+ DeviceDesc devices[] = {
+ {UINT32_MAX, "root_child1"}, {UINT32_MAX, "root_child2"}, {0, "root_child1_1"},
+ {0, "root_child1_2"}, {2, "root_child1_1_1"}, {1, "root_child2_1"},
+ };
+ for (auto& desc : devices) {
+ fbl::RefPtr<devmgr::Device> parent;
+ if (desc.parent_desc_index == UINT32_MAX) {
+ parent = platform_bus();
+ } else {
+ size_t index = devices[desc.parent_desc_index].index;
+ parent = device(index)->device;
+ }
+ ASSERT_NO_FATAL_FAILURES(AddDevice(parent, desc.name, 0 /* protocol id */, "", &desc.index));
+ }
+
+ ASSERT_NO_FATAL_FAILURES(DoResume(target_state));
+
+ // size_t num_to_resume = fbl::count_of(devices);
+ // while (num_to_resume > 0) {
+ // Check that platform bus received the resume first
+ ASSERT_TRUE(DeviceHasPendingMessages(platform_bus_remote()));
+ coordinator_loop()->RunUntilIdle();
+ ASSERT_NO_FATAL_FAILURES(CheckResumeReceived(platform_bus_remote(), target_state, ZX_OK));
+ //}
+}
+
+TEST_F(ResumeTestCase, FullyOnCheckOrder) {
+ ASSERT_NO_FATAL_FAILURES(ResumeTest(SystemPowerState::SYSTEM_POWER_STATE_FULLY_ON));
+}
+
class CompositeTestCase : public MultipleDeviceTestCase {
public:
~CompositeTestCase() override = default;
diff --git a/src/devices/coordinator/coordinator.cc b/src/devices/coordinator/coordinator.cc
index 76331ff..94a5a19 100644
--- a/src/devices/coordinator/coordinator.cc
+++ b/src/devices/coordinator/coordinator.cc
@@ -36,14 +36,15 @@
#include <zircon/syscalls/policy.h>
#include <zircon/syscalls/system.h>
+#include <cstdint>
#include <utility>
#include <ddk/driver.h>
#include <driver-info/driver-info.h>
#include <fbl/auto_call.h>
#include <fbl/unique_ptr.h>
-#include <libzbi/zbi-cpp.h>
#include <inspector/inspector.h>
+#include <libzbi/zbi-cpp.h>
#include "composite-device.h"
#include "devfs.h"
@@ -1175,8 +1176,7 @@
}
zx::unowned_process process = task.device().host()->proc();
char process_name[ZX_MAX_NAME_LEN];
- zx_status_t status = process->get_property(ZX_PROP_NAME, process_name,
- sizeof(process_name));
+ zx_status_t status = process->get_property(ZX_PROP_NAME, process_name, sizeof(process_name));
if (status != ZX_OK) {
strlcpy(process_name, "unknown", sizeof(process_name));
}
@@ -1233,32 +1233,68 @@
auto task = SuspendTask::Create(sys_device(), ctx.sflags(), std::move(completion));
suspend_context().set_task(std::move(task));
- auto status = async::PostDelayedTask(
- dispatcher(),
- [this, callback] {
- if (!InSuspend()) {
- return; // Suspend failed to complete.
- }
- auto& ctx = suspend_context();
- log(ERROR, "devcoordinator: DEVICE SUSPEND TIMED OUT\n");
- log(ERROR, " sflags: 0x%08x\n", ctx.sflags());
- dump_suspend_task_dependencies(ctx.task());
- if (suspend_fallback()) {
- ::suspend_fallback(root_resource(), ctx.sflags());
- // Unless in test env, we should not reach here.
- callback(ZX_ERR_TIMED_OUT);
- }
- },
- zx::sec(30));
+ auto status = async::PostDelayedTask(dispatcher(),
+ [this, callback] {
+ if (!InSuspend()) {
+ return; // Suspend failed to complete.
+ }
+ auto& ctx = suspend_context();
+ log(ERROR, "devcoordinator: DEVICE SUSPEND TIMED OUT\n");
+ log(ERROR, " sflags: 0x%08x\n", ctx.sflags());
+ dump_suspend_task_dependencies(ctx.task());
+ if (suspend_fallback()) {
+ ::suspend_fallback(root_resource(), ctx.sflags());
+ // Unless in test env, we should not reach here.
+ callback(ZX_ERR_TIMED_OUT);
+ }
+ },
+ zx::sec(30));
if (status != ZX_OK) {
log(ERROR, "devcoordinator: Failed to create suspend timeout watchdog\n");
}
}
+void Coordinator::Resume(ResumeContext ctx, std::function<void(zx_status_t)> callback) {
+ // The sys device should have a proxy. If not, the system hasn't fully initialized yet and
+ // cannot go to suspend.
+ if (!sys_device_->proxy()) {
+ return;
+ }
+ if (InSuspend()) {
+ return;
+ }
+
+ resume_context() = std::move(ctx);
+
+ auto completion = [this, callback](zx_status_t status) {
+ auto& ctx = resume_context();
+ if (status != ZX_OK) {
+ // do not continue to resume as this indicates a driver resume
+ // problem and should show as a bug
+ log(ERROR, "devcoordinator: failed to resume: %s\n", zx_status_get_string(status));
+ ctx.set_flags(devmgr::ResumeContext::Flags::kSuspended);
+ callback(status);
+ return;
+ }
+ callback(status);
+ };
+
+ printf("MINE MINE Reached Resume: Hippity Hoppity mood\n");
+ // We don't need to resume anything except sys_device and it's children,
+ // since we do not run suspend hooks for children of test or misc
+ auto task = ResumeTask::Create(sys_device(), static_cast<uint32_t>(ctx.target_state()),
+ std::move(completion));
+ resume_context().set_task(std::move(task));
+}
+
void Coordinator::Suspend(uint32_t flags) {
Suspend(SuspendContext(SuspendContext::Flags::kSuspend, flags), [](zx_status_t) {});
}
+void Coordinator::Resume(SystemPowerState target_state) {
+ Resume(ResumeContext(ResumeContext::Flags::kResume, target_state), [](zx_status_t) {});
+}
+
fbl::unique_ptr<Driver> Coordinator::ValidateDriver(fbl::unique_ptr<Driver> drv) {
if ((drv->flags & ZIRCON_DRIVER_NOTE_FLAG_ASAN) && !config_.asan_drivers) {
if (launched_first_devhost_) {
@@ -1544,6 +1580,20 @@
});
return ZX_ERR_ASYNC;
},
+ .Resume =
+ [](void* ctx, fuchsia_device_manager_SystemPowerState target_state, fidl_txn_t* txn) {
+ auto* async_txn = fidl_async_txn_create(txn);
+ static_cast<Coordinator*>(ctx)->Resume(
+ ResumeContext(
+ ResumeContext::Flags::kResume,
+ static_cast<llcpp::fuchsia::device::manager::SystemPowerState>(target_state)),
+ [async_txn](zx_status_t status) {
+ fuchsia_device_manager_AdministratorResume_reply(
+ fidl_async_txn_borrow(async_txn), status);
+ fidl_async_txn_complete(async_txn, true);
+ });
+ return ZX_ERR_ASYNC;
+ },
};
const auto status =
@@ -1554,7 +1604,7 @@
printf("Failed to bind to client channel: %d \n", status);
}
return status;
- };
+ }; // namespace devmgr
svc_dir->AddEntry(fuchsia_device_manager_Administrator_Name,
fbl::MakeRefCounted<fs::Service>(admin));
@@ -1594,7 +1644,7 @@
};
svc_dir->AddEntry(fuchsia_device_manager_DebugDumper_Name,
fbl::MakeRefCounted<fs::Service>(debug));
-}
+} // namespace devmgr
void Coordinator::OnOOMEvent(async_dispatcher_t* dispatcher, async::WaitBase* wait,
zx_status_t status, const zx_packet_signal_t* signal) {
diff --git a/src/devices/coordinator/coordinator.h b/src/devices/coordinator/coordinator.h
index d7a7435..f8f0eeb 100644
--- a/src/devices/coordinator/coordinator.h
+++ b/src/devices/coordinator/coordinator.h
@@ -27,11 +27,15 @@
#include "devhost.h"
#include "device.h"
#include "driver.h"
+#include "fuchsia/device/manager/llcpp/fidl.h"
#include "metadata.h"
+#include "resume-task.h"
#include "suspend-task.h"
#include "unbind-task.h"
#include "vmo-writer.h"
+using llcpp::fuchsia::device::manager::SystemPowerState;
+
namespace devmgr {
class DevhostLoaderService;
@@ -70,6 +74,36 @@
uint32_t sflags_ = 0u;
};
+class ResumeContext {
+ public:
+ enum class Flags : uint32_t {
+ kResume = 0u,
+ kSuspended = 1u,
+ };
+ ResumeContext() = default;
+
+ ResumeContext(Flags flags, SystemPowerState resume_state)
+ : target_state_(resume_state), flags_(flags) {}
+
+ ~ResumeContext() {}
+
+ ResumeContext(ResumeContext&&) = default;
+ ResumeContext& operator=(ResumeContext&&) = default;
+
+ Flags flags() const { return flags_; }
+ void set_flags(Flags flags) { flags_ = flags; }
+ void set_task(fbl::RefPtr<ResumeTask> task) { task_ = std::move(task); }
+
+ const ResumeTask& task() const { return *task_; }
+
+ SystemPowerState target_state() const { return target_state_; }
+
+ private:
+ fbl::RefPtr<ResumeTask> task_;
+ SystemPowerState target_state_;
+ Flags flags_ = Flags::kSuspended;
+};
+
// Values parsed out of argv. All paths described below are absolute paths.
struct DevmgrArgs {
// Load drivers from these directories. If this is empty, the default will
@@ -232,10 +266,14 @@
const fbl::RefPtr<Device>& test_device() { return test_device_; }
void Suspend(uint32_t flags);
+ void Resume(SystemPowerState target_state);
SuspendContext& suspend_context() { return suspend_context_; }
const SuspendContext& suspend_context() const { return suspend_context_; }
+ ResumeContext& resume_context() { return resume_context_; }
+ const ResumeContext& resume_context() const { return resume_context_; }
+
zx_status_t BindFidlServiceProxy(zx::channel listen_on);
zx_status_t BindOutgoingServices(zx::channel listen_on);
@@ -282,6 +320,7 @@
fbl::RefPtr<Device> test_device_;
SuspendContext suspend_context_;
+ ResumeContext resume_context_;
void OnOOMEvent(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
const zx_packet_signal_t* signal);
@@ -300,6 +339,7 @@
void BuildSuspendList();
void Suspend(SuspendContext ctx, std::function<void(zx_status_t)> callback);
+ void Resume(ResumeContext ctx, std::function<void(zx_status_t)> callback);
fbl::unique_ptr<Driver> ValidateDriver(fbl::unique_ptr<Driver> drv);
diff --git a/src/devices/coordinator/device.cc b/src/devices/coordinator/device.cc
index 486603a..49116e5 100644
--- a/src/devices/coordinator/device.cc
+++ b/src/devices/coordinator/device.cc
@@ -17,6 +17,7 @@
#include "fidl.h"
#include "fidl_txn.h"
#include "log.h"
+#include "resume-task.h"
#include "suspend-task.h"
namespace devmgr {
@@ -221,6 +222,17 @@
return active_suspend_;
}
+fbl::RefPtr<ResumeTask> Device::RequestResumeTask(uint32_t target_system_state) {
+ if (active_resume_) {
+ // We don't support different types of resumes concurrently, and
+ // shouldn't be able to reach this state.
+ ZX_ASSERT(target_system_state == active_resume_->target_system_state());
+ } else {
+ active_resume_ = ResumeTask::Create(fbl::RefPtr(this), target_system_state);
+ }
+ return active_resume_;
+}
+
zx_status_t Device::SendSuspend(uint32_t flags, SuspendCompletion completion) {
if (suspend_completion_) {
// We already have a pending suspend
@@ -236,6 +248,21 @@
return ZX_OK;
}
+zx_status_t Device::SendResume(uint32_t target_system_state, ResumeCompletion completion) {
+ if (resume_completion_) {
+ // We already have a pending resume
+ return ZX_ERR_UNAVAILABLE;
+ }
+ log(DEVLC, "devcoordinator: resume dev %p name='%s'\n", this, name_.data());
+ zx_status_t status = dh_send_resume(this, target_system_state);
+ if (status != ZX_OK) {
+ return status;
+ }
+ state_ = Device::State::kResuming;
+ resume_completion_ = std::move(completion);
+ return ZX_OK;
+}
+
void Device::CompleteSuspend(zx_status_t status) {
if (status == ZX_OK) {
// If a device is being removed, any existing suspend task will be forcibly completed,
@@ -253,6 +280,17 @@
}
}
+void Device::CompleteResume(zx_status_t status) {
+ if (status != ZX_OK) {
+ state_ = Device::State::kSuspended;
+ } else {
+ state_ = Device::State::kResumed;
+ }
+ if (resume_completion_) {
+ resume_completion_(status);
+ }
+}
+
void Device::CreateUnbindRemoveTasks(UnbindTaskOpts opts) {
if (state_ == Device::State::kDead) {
return;
@@ -287,10 +325,10 @@
}
}
} else {
- // |do_unbind| may not match the stored field in the existing unbind task due to
- // the current device_remove / unbind model.
- // For closest compatibility with the current model, we should prioritize
- // devhost calls to |ScheduleRemove| over our own scheduled unbind tasks for the children.
+ // |do_unbind| may not match the stored field in the existing unbind task due to
+ // the current device_remove / unbind model.
+ // For closest compatibility with the current model, we should prioritize
+ // devhost calls to |ScheduleRemove| over our own scheduled unbind tasks for the children.
active_unbind_->set_do_unbind(opts.do_unbind);
}
}
@@ -595,6 +633,29 @@
}
log(DEVLC, "devcoordinator: suspended dev %p name='%s'\n", this, name_.data());
CompleteSuspend(resp->status);
+ } else if (ordinal == fuchsia_device_manager_DeviceControllerResumeOrdinal ||
+ ordinal == fuchsia_device_manager_DeviceControllerResumeGenOrdinal) {
+ const char* err_msg = nullptr;
+ r = fidl_decode_msg(&fuchsia_device_manager_DeviceControllerResumeResponseTable, &fidl_msg,
+ &err_msg);
+ if (r != ZX_OK) {
+ log(ERROR, "devcoordinator: rpc: suspend '%s' received malformed reply: %s\n", name_.data(),
+ err_msg);
+ return ZX_ERR_IO;
+ }
+ auto resp =
+ reinterpret_cast<fuchsia_device_manager_DeviceControllerResumeResponse*>(fidl_msg.bytes);
+ if (resp->status != ZX_OK) {
+ log(ERROR, "devcoordinator: rpc: resume '%s' status %d\n", name_.data(), resp->status);
+ }
+
+ if (!resume_completion_) {
+ log(ERROR, "devcoordinator: rpc: unexpected resume reply for '%s' status %d\n", name_.data(),
+ resp->status);
+ return ZX_ERR_IO;
+ }
+ log(INFO, "devcoordinator: resumed dev %p name='%s'\n", this, name_.data());
+ CompleteResume(resp->status);
} else {
log(ERROR, "devcoordinator: rpc: dev '%s' received wrong unexpected reply %16lx\n",
name_.data(), hdr->ordinal);
diff --git a/src/devices/coordinator/device.h b/src/devices/coordinator/device.h
index 4521e7a..e96d5d2 100644
--- a/src/devices/coordinator/device.h
+++ b/src/devices/coordinator/device.h
@@ -34,6 +34,7 @@
class RemoveTask;
class SuspendContext;
class SuspendTask;
+class ResumeTask;
class UnbindTask;
struct UnbindTaskOpts;
@@ -305,6 +306,11 @@
// given completion will be invoked.
zx_status_t SendSuspend(uint32_t flags, SuspendCompletion completion);
+ using ResumeCompletion = fit::callback<void(zx_status_t)>;
+ // Issue a Resume request to this device. When the response comes in, the
+ // given completion will be invoked.
+ zx_status_t SendResume(uint32_t target_system_state, ResumeCompletion completion);
+
using UnbindCompletion = fit::callback<void(zx_status_t)>;
using RemoveCompletion = fit::callback<void(zx_status_t)>;
// Issue an Unbind request to this device, which will run the unbind hook.
@@ -377,11 +383,22 @@
// Creates a new suspend task if necessary and returns a reference to it.
// If one is already in-progress, a reference to it is returned instead
fbl::RefPtr<SuspendTask> RequestSuspendTask(uint32_t suspend_flags);
+
+ fbl::RefPtr<ResumeTask> GetActiveResume() { return active_resume_; }
+
+ // Request Resume task
+ fbl::RefPtr<ResumeTask> RequestResumeTask(uint32_t system_resume_state);
+
// Run the completion for the outstanding suspend, if any. This method is
// only exposed currently because RemoveDevice is on Coordinator instead of
// Device.
void CompleteSuspend(zx_status_t status);
+ // Run the completion for the outstanding suspend, if any. This method is
+ // only exposed currently because RemoveDevice is on Coordinator instead of
+ // Device.
+ void CompleteResume(zx_status_t status);
+
// Creates the unbind and remove tasks for the device if they do not already exist.
// |opts| is used to configure the unbind task.
void CreateUnbindRemoveTasks(UnbindTaskOpts opts);
@@ -426,6 +443,8 @@
kActive,
kSuspending, // The devhost is in the process of suspending the device.
kSuspended,
+ kResuming, // The devhost is in the process of resuming the device.
+ kResumed, // Resume is complete.The device marked active, after all children are resumed.
kUnbinding, // The devhost is in the process of unbinding and removing the device.
kDead, // The device has been remove()'d
};
@@ -457,6 +476,8 @@
fbl::AutoLock<fbl::Mutex> lock(&test_state_lock_);
test_state_ = new_state;
}
+
+ void clear_active_resume() { active_resume_ = nullptr; }
void set_test_time(zx::duration& test_time) { test_time_ = test_time; }
void set_test_reply_required(bool required) { test_reply_required_ = required; }
zx::duration& test_time() { return test_time_; }
@@ -534,6 +555,12 @@
// it.
SuspendCompletion suspend_completion_;
+ // If a resume is in-progress, this task represents it.
+ fbl::RefPtr<ResumeTask> active_resume_;
+ // If a Resume is in-progress, this completion will be invoked when it is
+ // completed.
+ ResumeCompletion resume_completion_;
+
// If an unbind is in-progress, this task represents it.
fbl::RefPtr<UnbindTask> active_unbind_;
// If an unbind is in-progress, this completion will be invoked when it is
diff --git a/src/devices/coordinator/fidl.cc b/src/devices/coordinator/fidl.cc
index 24bb967..3ebb830 100644
--- a/src/devices/coordinator/fidl.cc
+++ b/src/devices/coordinator/fidl.cc
@@ -151,6 +151,21 @@
return msg.Write(dev->channel()->get(), 0);
}
+zx_status_t dh_send_resume(const Device* dev, uint32_t target_system_state) {
+ FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_DeviceControllerResumeRequest)];
+ fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
+
+ auto req = builder.New<fuchsia_device_manager_DeviceControllerResumeRequest>();
+ ZX_ASSERT(req != nullptr);
+ req->hdr.ordinal = fuchsia_device_manager_DeviceControllerResumeOrdinal;
+ // TODO(teisenbe): Allocate and track txids
+ req->hdr.txid = 1;
+ req->target_system_state = target_system_state;
+
+ fidl::Message msg(builder.Finalize(), fidl::HandlePart(nullptr, 0));
+ return msg.Write(dev->channel()->get(), 0);
+}
+
zx_status_t dh_send_complete_compatibility_tests(const Device* dev, zx_status_t status) {
FIDL_ALIGNDECL char
wr_bytes[sizeof(fuchsia_device_manager_DeviceControllerCompleteCompatibilityTestsRequest)];
diff --git a/src/devices/coordinator/fidl.h b/src/devices/coordinator/fidl.h
index 9f9cccb..a46d1f0 100644
--- a/src/devices/coordinator/fidl.h
+++ b/src/devices/coordinator/fidl.h
@@ -23,6 +23,7 @@
zx_status_t dh_send_bind_driver(const Device* dev, const char* libname, zx::vmo driver);
zx_status_t dh_send_connect_proxy(const Device* dev, zx::channel proxy);
zx_status_t dh_send_suspend(const Device* dev, uint32_t flags);
+zx_status_t dh_send_resume(const Device* dev, uint32_t target_system_state);
zx_status_t dh_send_unbind(const Device* dev);
zx_status_t dh_send_complete_removal(const Device* dev);
zx_status_t dh_send_complete_compatibility_tests(const Device* dev, zx_status_t test_status_);
diff --git a/src/devices/coordinator/resume-task.cc b/src/devices/coordinator/resume-task.cc
new file mode 100644
index 0000000..73abb86
--- /dev/null
+++ b/src/devices/coordinator/resume-task.cc
@@ -0,0 +1,182 @@
+// 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 "resume-task.h"
+
+#include "coordinator.h"
+
+namespace devmgr {
+
+ResumeTask::ResumeTask(fbl::RefPtr<Device> device, uint32_t target_system_state,
+ Completion completion)
+ : Task(device->coordinator->dispatcher(), std::move(completion)),
+ device_(std::move(device)),
+ target_system_state_(target_system_state) {}
+
+ResumeTask::~ResumeTask() = default;
+
+fbl::RefPtr<ResumeTask> ResumeTask::Create(fbl::RefPtr<Device> device, uint32_t target_system_state,
+ Completion completion) {
+ return fbl::MakeRefCounted<ResumeTask>(std::move(device), target_system_state,
+ std::move(completion));
+}
+
+bool ResumeTask::AddChildResumeTasks() {
+ bool found_more_dependencies = false;
+ printf("AddChildResumeTasks START for %s\n", device_->name().data());
+ for (auto& child : device_->children()) {
+ // Use a switch statement here so that this gets reconsidered if we add
+ // more states.
+ switch (child.state()) {
+ // If the device is dead, any existing resume task would have been forcibly completed.
+ case Device::State::kDead:
+ case Device::State::kActive:
+ continue;
+ case Device::State::kUnbinding:
+ case Device::State::kSuspending:
+ case Device::State::kResuming:
+ case Device::State::kResumed:
+ case Device::State::kSuspended:
+ printf("Adding resume task for dependency for child: %s\n", child.name().data());
+ AddDependency(child.RequestResumeTask(target_system_state_));
+ found_more_dependencies = true;
+ break;
+ }
+ }
+ printf("AddChildResumeTasks STOP for %s. found_more_deps: %d\n", device_->name().data(),
+ found_more_dependencies);
+ return found_more_dependencies;
+}
+
+void ResumeTask::Run() {
+ switch (device_->state()) {
+ case Device::State::kDead:
+ case Device::State::kActive:
+ return Complete(ZX_OK);
+ case Device::State::kSuspending:
+ case Device::State::kUnbinding:
+ case Device::State::kSuspended:
+ case Device::State::kResumed:
+ case Device::State::kResuming:
+ break;
+ }
+
+ // The device is about to be unbound, wait for it to complete.
+ // Eventually we complete when device goes to DEAD
+ if (device_->state() == Device::State::kUnbinding) {
+ // The remove task depends on the unbind task, so wait for that to complete.
+ auto remove_task = device_->GetActiveRemove();
+ ZX_ASSERT(remove_task != nullptr);
+ AddDependency(remove_task);
+ return;
+ }
+
+ // The device is about to be suspended, wait for it to complete.
+ if (device_->state() == Device::State::kSuspending) {
+ auto suspend_task = device_->GetActiveSuspend();
+ ZX_ASSERT(suspend_task != nullptr);
+ AddDependency(suspend_task);
+ return;
+ }
+
+ auto completion = [this](zx_status_t status) {
+ if (status != ZX_OK) {
+ printf("MINE MINE : ResumeTask:%s :RESUME HOOK FAILED\n", device_->name().data());
+ return Complete(status);
+ }
+ // Handle the device proxy, if it exists, before children since they might
+ // depend on it.
+ if (device_->proxy() != nullptr) {
+ switch (device_->proxy()->state()) {
+ case Device::State::kDead:
+ // Proxy is dead. We cannot resume devices under. Complete with ZX_OK.
+ // We should not consider this error.
+ return Complete(ZX_OK);
+ case Device::State::kActive:
+ break;
+ case Device::State::kSuspending:
+ case Device::State::kUnbinding:
+ case Device::State::kSuspended:
+ case Device::State::kResumed:
+ case Device::State::kResuming:
+ printf("Adding resume task for dependency for device: %s proxy device: %s\n",
+ device_->name().data(), device_->proxy()->name().data());
+ AddDependency(device_->proxy()->RequestResumeTask(target_system_state_));
+ child_resume_tasks_not_issued_ = true;
+ return;
+ }
+ }
+ child_resume_tasks_not_issued_ = false;
+ if (AddChildResumeTasks()) {
+ return;
+ }
+
+ printf("MINE MINE : ResumeTask:%s :COMPLETE: No more children\n", device_->name().data());
+ device_->set_state(Device::State::kActive);
+ device_->clear_active_resume();
+ return Complete(ZX_OK);
+ };
+
+ if (device_->state() == Device::State::kSuspended) {
+ printf("MINE MINE : ResumeTask: %s: START: devstate: SUSPENDED\n", device_->name().data());
+ if (device_->host() == nullptr) {
+ // pretend this completed successfully.
+ device_->set_state(Device::State::kResumed);
+ printf("MINE MINE : ResumeTask: %s No HOST.\n", device_->name().data());
+ child_resume_tasks_not_issued_ = true;
+ completion(ZX_OK);
+ return;
+ } else {
+ printf("MINE MINE : ResumeTask: %s SENDING RESUME\n", device_->name().data());
+ zx_status_t status = device_->SendResume(target_system_state_, std::move(completion));
+ if (status != ZX_OK) {
+ printf("MINE MINE : ResumeTask:%s COMPLETE: SEND RESUME FAILED\n", device_->name().data());
+ device_->clear_active_resume();
+ return Complete(status);
+ }
+ }
+ }
+
+ // This means this device's resume is complete and we need to handle the children.
+ if (device_->state() == Device::State::kResumed) {
+ // We come back here after proxy resume is complete unless it failed We cannot resume devices
+ // under, unless proxy is active. We should not consider this error, because we do not want
+ // resume task to fail, only because we have a device removed.
+ if (device_->proxy() != nullptr && device_->proxy()->state() != Device::State::kActive) {
+ printf("MINE MINE : ResumeTask:%s proxy state: %d\n", device_->name().data(),
+ device_->proxy()->state());
+ device_->set_state(Device::State::kActive);
+ device_->clear_active_resume();
+ return Complete(ZX_OK);
+ }
+ if (child_resume_tasks_not_issued_) {
+ child_resume_tasks_not_issued_ = false;
+ if (AddChildResumeTasks()) {
+ for (auto* dependency : Dependencies()) {
+ printf("The dependency %s added\n",
+ reinterpret_cast<const ResumeTask*>(dependency)->device().name().data());
+ }
+ return;
+ }
+ printf("MINE MINE : ResumeTask:%s COMPLETE: ADD CHILDREN FAILED\n", device_->name().data());
+ device_->set_state(Device::State::kActive);
+ device_->clear_active_resume();
+ return Complete(ZX_OK);
+ }
+ // we have completed all dependencies. We should return ZX_OK, because
+ // this device has been resumed, although children are all not resumed.
+ // Complete the ResumeTask.
+ device_->set_state(Device::State::kActive);
+ device_->clear_active_resume();
+ printf("MINE MINE : ResumeTask: Completed all dependencies for %s\n", device_->name().data());
+ for (auto* dependency : Dependencies()) {
+ if (dependency->is_completed()) {
+ printf("The dependency %s complete\n",
+ reinterpret_cast<const ResumeTask*>(dependency)->device().name().data());
+ }
+ }
+ Complete(ZX_OK);
+ }
+}
+} // namespace devmgr
diff --git a/src/devices/coordinator/resume-task.h b/src/devices/coordinator/resume-task.h
new file mode 100644
index 0000000..42c6455
--- /dev/null
+++ b/src/devices/coordinator/resume-task.h
@@ -0,0 +1,40 @@
+// 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.
+
+#ifndef ZIRCON_SYSTEM_CORE_DEVMGR_DEVCOORDINATOR_RESUME_TASK_H_
+#define ZIRCON_SYSTEM_CORE_DEVMGR_DEVCOORDINATOR_RESUME_TASK_H_
+
+#include "device.h"
+#include "task.h"
+
+namespace devmgr {
+
+class ResumeTask final : public Task {
+ public:
+ static fbl::RefPtr<ResumeTask> Create(fbl::RefPtr<Device> device, uint32_t target_system_state,
+ Completion completion = nullptr);
+
+ // Don/t invoke this, use Create
+ ResumeTask(fbl::RefPtr<Device> device, uint32_t target_system_state, Completion completion);
+
+ uint32_t target_system_state() { return target_system_state_; }
+
+ ~ResumeTask() final;
+
+ const Device& device() const { return *device_; }
+
+ private:
+ void Run() final;
+ bool AddChildResumeTasks();
+
+ // The device being resumeed
+ fbl::RefPtr<Device> device_;
+ // Target system resume state
+ uint32_t target_system_state_;
+ bool child_resume_tasks_not_issued_ = false;
+};
+
+} // namespace devmgr
+
+#endif // ZIRCON_SYSTEM_CORE_DEVMGR_DEVCOORDINATOR_RESUME_TASK_H_
diff --git a/src/devices/coordinator/suspend-task.cc b/src/devices/coordinator/suspend-task.cc
index bec4c3a3..4800bb2 100644
--- a/src/devices/coordinator/suspend-task.cc
+++ b/src/devices/coordinator/suspend-task.cc
@@ -33,6 +33,8 @@
case Device::State::kUnbinding:
case Device::State::kSuspending:
case Device::State::kActive:
+ case Device::State::kResuming:
+ case Device::State::kResumed:
break;
}
@@ -49,6 +51,8 @@
switch (device_->proxy()->state()) {
case Device::State::kDead:
case Device::State::kSuspended:
+ case Device::State::kResuming:
+ case Device::State::kResumed:
break;
case Device::State::kUnbinding:
case Device::State::kSuspending:
@@ -68,14 +72,25 @@
return;
}
+ // The device is about to be resumed, wait for it to complete.
+ if (device_->state() == Device::State::kResuming) {
+ auto resume_task = device_->GetActiveResume();
+ AddDependency(resume_task);
+ return;
+ }
+
// Check if this device is not in a devhost. This happens for the
// top-level devices like /sys provided by devcoordinator,
// or the device is already dead.
if (device_->host() == nullptr) {
+ device_->set_state(Device::State::kSuspended);
return Complete(ZX_OK);
}
- auto completion = [this](zx_status_t status) { Complete(status); };
+ auto completion = [this](zx_status_t status) {
+ device_->set_state(Device::State::kSuspended);
+ Complete(status);
+ };
zx_status_t status = device_->SendSuspend(flags_, std::move(completion));
if (status != ZX_OK) {
Complete(status);
diff --git a/src/devices/coordinator/unbind-task.cc b/src/devices/coordinator/unbind-task.cc
index 6227cd6..ba0dc2d6 100644
--- a/src/devices/coordinator/unbind-task.cc
+++ b/src/devices/coordinator/unbind-task.cc
@@ -44,6 +44,8 @@
case Device::State::kSuspended:
// The created unbind task will wait for the suspend to complete.
case Device::State::kSuspending:
+ case Device::State::kResuming:
+ case Device::State::kResumed:
case Device::State::kActive: {
device_->proxy()->CreateUnbindRemoveTasks(UnbindTaskOpts{
.do_unbind = false, .post_on_create = false, .devhost_requested = false});
@@ -83,6 +85,8 @@
continue;
case Device::State::kSuspended:
case Device::State::kSuspending:
+ case Device::State::kResuming:
+ case Device::State::kResumed:
case Device::State::kActive:
break;
}
@@ -120,6 +124,13 @@
return;
}
+ if (device_->state() == Device::State::kResuming) {
+ auto resume_task = device_->GetActiveResume();
+ ZX_ASSERT(resume_task != nullptr);
+ AddDependency(resume_task);
+ return;
+ }
+
// We need to schedule the child tasks before completing the unbind task runs,
// as composite device disassociation may occur.
ScheduleUnbindChildren();
diff --git a/src/modular/tests/sessionmgr_integration_test.cc b/src/modular/tests/sessionmgr_integration_test.cc
index 8f4dda9..b8cda40 100644
--- a/src/modular/tests/sessionmgr_integration_test.cc
+++ b/src/modular/tests/sessionmgr_integration_test.cc
@@ -17,6 +17,7 @@
class MockAdmin : public fuchsia::device::manager::Administrator {
public:
bool suspend_called() { return suspend_called_; }
+ bool resume_called() { return resume_called_; }
private:
void Suspend(uint32_t flags, SuspendCallback callback) override {
@@ -26,7 +27,15 @@
callback(ZX_OK);
}
+ void Resume(fuchsia::device::manager::SystemPowerState target_state,
+ ResumeCallback callback) override {
+ ASSERT_FALSE(resume_called_);
+ resume_called_ = true;
+ callback(ZX_OK);
+ }
+
bool suspend_called_ = false;
+ bool resume_called_ = false;
};
TEST_F(SessionmgrIntegrationTest, RebootCalledIfSessionmgrCrashNumberReachesRetryLimit) {
diff --git a/src/recovery/factory_reset/factory_reset_unittest.cc b/src/recovery/factory_reset/factory_reset_unittest.cc
index 30cf04b..2cef037 100644
--- a/src/recovery/factory_reset/factory_reset_unittest.cc
+++ b/src/recovery/factory_reset/factory_reset_unittest.cc
@@ -4,10 +4,7 @@
#include "factory_reset.h"
-#include <fbl/algorithm.h>
#include <fcntl.h>
-#include <fs-management/fvm.h>
-#include <fs-management/mount.h>
#include <fuchsia/device/manager/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
@@ -17,9 +14,13 @@
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fzl/fdio.h>
#include <lib/zx/vmo.h>
-#include <ramdevice-client/ramdisk.h>
#include <zircon/hw/gpt.h>
+#include <fbl/algorithm.h>
+#include <fs-management/fvm.h>
+#include <fs-management/mount.h>
+#include <ramdevice-client/ramdisk.h>
+
#include "gtest/gtest.h"
namespace {
@@ -37,6 +38,7 @@
class MockAdmin : public fuchsia::device::manager::Administrator {
public:
bool suspend_called() { return suspend_called_; }
+ bool resume_called() { return resume_called_; }
private:
void Suspend(uint32_t flags, SuspendCallback callback) override {
@@ -46,7 +48,14 @@
callback(ZX_OK);
}
+ void Resume(fuchsia::device::manager::SystemPowerState state, ResumeCallback callback) override {
+ ASSERT_FALSE(resume_called_);
+ resume_called_ = true;
+ callback(ZX_OK);
+ }
+
bool suspend_called_ = false;
+ bool resume_called_ = false;
};
class FactoryResetTest : public Test {
diff --git a/zircon/system/core/devmgr/devhost/core.cc b/zircon/system/core/devmgr/devhost/core.cc
index a439db9..e387b1c 100644
--- a/zircon/system/core/devmgr/devhost/core.cc
+++ b/zircon/system/core/devmgr/devhost/core.cc
@@ -3,11 +3,7 @@
// found in the LICENSE file.
#include <assert.h>
-#include <ddk/device.h>
-#include <ddk/driver.h>
#include <errno.h>
-#include <fbl/auto_call.h>
-#include <fbl/auto_lock.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
@@ -20,10 +16,15 @@
#include <zircon/syscalls.h>
#include <zircon/types.h>
+#include <array>
#include <atomic>
#include <new>
#include <utility>
-#include <array>
+
+#include <ddk/device.h>
+#include <ddk/driver.h>
+#include <fbl/auto_call.h>
+#include <fbl/auto_lock.h>
#include "composite-device.h"
#include "devhost.h"
@@ -81,7 +82,9 @@
static zx_status_t default_suspend(void* ctx, uint32_t flags) { return ZX_ERR_NOT_SUPPORTED; }
-static zx_status_t default_resume(void* ctx, uint32_t flags) { return ZX_ERR_NOT_SUPPORTED; }
+static zx_status_t default_resume(void* ctx, uint32_t target_system_state) {
+ return ZX_ERR_NOT_SUPPORTED;
+}
static zx_status_t default_rxrpc(void* ctx, zx_handle_t channel) { return ZX_ERR_NOT_SUPPORTED; }
@@ -453,7 +456,6 @@
// Ask the devcoordinator to schedule the removal of this device and its children.
devhost_schedule_remove(dev, unbind_self);
return ZX_OK;
-
}
void devhost_device_unbind_reply(const fbl::RefPtr<zx_device_t>& dev) REQ_DM_LOCK {
@@ -567,8 +569,8 @@
return dev->CloseOp(flags);
}
-zx_status_t devhost_device_get_dev_power_state_from_mapping(const fbl::RefPtr<zx_device>& dev,
- uint32_t flags, fuchsia_device_SystemPowerStateInfo* info) {
+zx_status_t devhost_device_get_dev_power_state_from_mapping(
+ const fbl::RefPtr<zx_device>& dev, uint32_t flags, fuchsia_device_SystemPowerStateInfo* info) {
// TODO(ravoorir) : When the usage of suspend flags is replaced with
// system power states, this function will not need the switch case.
// Some suspend flags might be translated to system power states with
@@ -595,8 +597,8 @@
return ZX_ERR_INVALID_ARGS;
}
const std::array<fuchsia_device_SystemPowerStateInfo,
- fuchsia_device_manager_MAX_SYSTEM_POWER_STATES>& sys_power_states =
- dev->GetSystemPowerStateMapping();
+ fuchsia_device_manager_MAX_SYSTEM_POWER_STATES>& sys_power_states =
+ dev->GetSystemPowerStateMapping();
*info = sys_power_states[sys_state];
return ZX_OK;
}
@@ -631,13 +633,42 @@
return ZX_OK;
}
+zx_status_t devhost_device_resume(const fbl::RefPtr<zx_device>& dev,
+ uint32_t target_system_state) REQ_DM_LOCK {
+ enum_lock_acquire();
+
+ zx_status_t status = ZX_ERR_NOT_SUPPORTED;
+ // If new suspend hook is implemented, prefer that.
+ if (dev->ops->resume_new) {
+ fuchsia_device_DevicePowerState out_state;
+ ApiAutoRelock relock;
+ const std::array<fuchsia_device_SystemPowerStateInfo,
+ fuchsia_device_manager_MAX_SYSTEM_POWER_STATES>& sys_power_states =
+ dev->GetSystemPowerStateMapping();
+ status =
+ dev->ops->resume_new(dev->ctx, sys_power_states[target_system_state].dev_state, &out_state);
+ } else if (dev->ops->resume) {
+ // Invoke resume hook otherwise.
+ ApiAutoRelock relock;
+ status = dev->ops->resume(dev->ctx, target_system_state);
+ }
+
+ enum_lock_release();
+
+ // default_resume() returns ZX_ERR_NOT_SUPPORTED
+ if ((status != ZX_OK) && (status != ZX_ERR_NOT_SUPPORTED)) {
+ return status;
+ }
+ return ZX_OK;
+}
+
zx_status_t devhost_device_suspend_new(const fbl::RefPtr<zx_device>& dev,
fuchsia_device_DevicePowerState requested_state,
fuchsia_device_DevicePowerState* out_state) {
zx_status_t status = ZX_OK;
if (dev->ops->suspend_new) {
- status = dev->ops->suspend_new(dev->ctx, requested_state, false /* wake_configured */,
- out_state);
+ status =
+ dev->ops->suspend_new(dev->ctx, requested_state, false /* wake_configured */, out_state);
}
return status;
}
diff --git a/zircon/system/core/devmgr/devhost/devhost.h b/zircon/system/core/devmgr/devhost/devhost.h
index c74ecf8..9f7e7e4 100644
--- a/zircon/system/core/devmgr/devhost/devhost.h
+++ b/zircon/system/core/devmgr/devhost/devhost.h
@@ -161,6 +161,7 @@
zx_status_t devhost_device_suspend_new(const fbl::RefPtr<zx_device_t>& dev,
fuchsia_device_DevicePowerState requested_state,
fuchsia_device_DevicePowerState *out_state);
+zx_status_t devhost_device_resume(const fbl::RefPtr<zx_device_t>& dev, uint32_t target_system_state) REQ_DM_LOCK;
zx_status_t devhost_device_resume_new(const fbl::RefPtr<zx_device_t>& dev,
fuchsia_device_DevicePowerState requested_state,
fuchsia_device_DevicePowerState *out_state);
diff --git a/zircon/system/core/devmgr/devhost/device-controller-connection.cc b/zircon/system/core/devmgr/devhost/device-controller-connection.cc
index 182b322..de4e8f3 100644
--- a/zircon/system/core/devmgr/devhost/device-controller-connection.cc
+++ b/zircon/system/core/devmgr/devhost/device-controller-connection.cc
@@ -61,6 +61,15 @@
completer.Reply(r);
}
+void DeviceControllerConnection::Resume(uint32_t target_system_state, ResumeCompleter::Sync completer) {
+ zx_status_t r;
+ {
+ ApiAutoLock lock;
+ r = devhost_device_resume(this->dev(), target_system_state);
+ }
+ completer.Reply(r);
+}
+
void DeviceControllerConnection::ConnectProxy(::zx::channel shadow,
ConnectProxyCompleter::Sync _completer) {
log(RPC_SDW, "devhost connect proxy rpc\n");
diff --git a/zircon/system/core/devmgr/devhost/device-controller-connection.h b/zircon/system/core/devmgr/devhost/device-controller-connection.h
index 55640013..c0608e5 100644
--- a/zircon/system/core/devmgr/devhost/device-controller-connection.h
+++ b/zircon/system/core/devmgr/devhost/device-controller-connection.h
@@ -43,6 +43,7 @@
void ConnectProxy(::zx::channel shadow, ConnectProxyCompleter::Sync _completer) override;
void RemoveDevice(RemoveDeviceCompleter::Sync _completer) override;
void Suspend(uint32_t flags, SuspendCompleter::Sync _completer) override;
+ void Resume(uint32_t target_system_state, ResumeCompleter::Sync _completer) override;
void Unbind(UnbindCompleter::Sync _completer) override;
void CompleteRemoval(CompleteRemovalCompleter::Sync _completer) override;
void CompleteCompatibilityTests(llcpp::fuchsia::device::manager::CompatibilityTestStatus status,
diff --git a/zircon/system/dev/test/ddk-power/test-driver-child.cc b/zircon/system/dev/test/ddk-power/test-driver-child.cc
index a95623e..7f2002f 100644
--- a/zircon/system/dev/test/ddk-power/test-driver-child.cc
+++ b/zircon/system/dev/test/ddk-power/test-driver-child.cc
@@ -2,6 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <fuchsia/device/power/test/llcpp/fidl.h>
+#include <lib/fdio/fd.h>
+#include <lib/fdio/fdio.h>
+#include <lib/fdio/namespace.h>
+#include <lib/fdio/spawn.h>
+#include <lib/fdio/unsafe.h>
+#include <lib/fdio/watcher.h>
+
#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
@@ -11,32 +19,22 @@
#include <ddktl/fidl.h>
#include <fbl/alloc_checker.h>
#include <fbl/auto_call.h>
-#include <fuchsia/device/power/test/llcpp/fidl.h>
-#include <lib/fdio/fd.h>
-#include <lib/fdio/fdio.h>
-#include <lib/fdio/namespace.h>
-#include <lib/fdio/spawn.h>
-#include <lib/fdio/unsafe.h>
-#include <lib/fdio/watcher.h>
using llcpp::fuchsia::device::DevicePowerStateInfo;
using llcpp::fuchsia::device::power::test::TestDevice;
class TestPowerDriverChild;
-using DeviceType = ddk::Device<TestPowerDriverChild, ddk::Unbindable, ddk::Messageable, ddk::SuspendableNew,
- ddk::ResumableNew>;
-class TestPowerDriverChild : public DeviceType,
- public TestDevice::Interface {
+using DeviceType = ddk::Device<TestPowerDriverChild, ddk::Unbindable, ddk::Messageable,
+ ddk::SuspendableNew, ddk::ResumableNew>;
+class TestPowerDriverChild : public DeviceType, public TestDevice::Interface {
public:
TestPowerDriverChild(zx_device_t* parent) : DeviceType(parent) {}
static zx_status_t Create(void* ctx, zx_device_t* device);
zx_status_t Bind();
- void DdkUnbind() {
- DdkRemove();
- }
+ void DdkUnbind() { DdkRemove(); }
void AddDeviceWithPowerArgs(::fidl::VectorView<DevicePowerStateInfo> info,
- AddDeviceWithPowerArgsCompleter::Sync completer) override;
+ AddDeviceWithPowerArgsCompleter::Sync completer) override;
void GetCurrentDevicePowerState(GetCurrentDevicePowerStateCompleter::Sync completer) override;
zx_status_t DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn) {
@@ -62,6 +60,7 @@
zx_status_t TestPowerDriverChild::DdkResumeNew(uint8_t requested_state, uint8_t* out_state) {
current_power_state_ = requested_state;
+ printf("MINE MINE Reached test-driver-child current_power_state: %d\n", current_power_state_);
*out_state = requested_state;
return ZX_OK;
}
@@ -87,7 +86,7 @@
states[i].system_wake_state = state_info[i].system_wake_state;
}
zx_status_t status = child2->DdkAdd("power-test-child-2", 0, nullptr, 0, 0, nullptr,
- ZX_HANDLE_INVALID, states.get(), count);
+ ZX_HANDLE_INVALID, states.get(), count);
if (status != ZX_OK) {
response.set_err(status);
} else {
@@ -98,18 +97,18 @@
completer.Reply(std::move(response));
}
-void TestPowerDriverChild::GetCurrentDevicePowerState(GetCurrentDevicePowerStateCompleter::Sync completer) {
+void TestPowerDriverChild::GetCurrentDevicePowerState(
+ GetCurrentDevicePowerStateCompleter::Sync completer) {
::llcpp::fuchsia::device::power::test::TestDevice_GetCurrentDevicePowerState_Result result;
- result.set_response(llcpp::fuchsia::device::power::test::TestDevice_GetCurrentDevicePowerState_Response{
- .cur_state = static_cast<llcpp::fuchsia::device::DevicePowerState>(current_power_state_),
- });
+ result.set_response(
+ llcpp::fuchsia::device::power::test::TestDevice_GetCurrentDevicePowerState_Response{
+ .cur_state = static_cast<llcpp::fuchsia::device::DevicePowerState>(current_power_state_),
+ });
completer.Reply(std::move(result));
}
-zx_status_t TestPowerDriverChild::Bind() {
- return DdkAdd("power-test-child");
-}
+zx_status_t TestPowerDriverChild::Bind() { return DdkAdd("power-test-child"); }
zx_status_t TestPowerDriverChild::Create(void* ctx, zx_device_t* device) {
fbl::AllocChecker ac;
@@ -137,4 +136,4 @@
ZIRCON_DRIVER_BEGIN(TestPowerChild, test_power_child_driver_ops, "zircon", "0.1", 1)
BI_MATCH_IF(EQ, BIND_PROTOCOL, ZX_PROTOCOL_TEST_POWER_CHILD),
ZIRCON_DRIVER_END(TestPowerChild)
-// clang-format on
+ // clang-format on
diff --git a/zircon/system/dev/test/ddk-power/test-driver.cc b/zircon/system/dev/test/ddk-power/test-driver.cc
index 99c2271..687a5c6 100644
--- a/zircon/system/dev/test/ddk-power/test-driver.cc
+++ b/zircon/system/dev/test/ddk-power/test-driver.cc
@@ -20,7 +20,7 @@
class TestPowerDriver;
using DeviceType =
- ddk::Device<TestPowerDriver, ddk::Unbindable, ddk::Suspendable, ddk::Messageable>;
+ ddk::Device<TestPowerDriver, ddk::Unbindable, ddk::Suspendable, ddk::Resumable, ddk::Messageable>;
class TestPowerDriver : public DeviceType,
public ddk::EmptyProtocol<ZX_PROTOCOL_TEST_POWER_CHILD>,
public TestDevice::Interface {
@@ -34,6 +34,11 @@
current_power_state_ = DevicePowerState::DEVICE_POWER_STATE_D1;
return ZX_OK;
}
+ zx_status_t DdkResume(uint32_t flags) {
+ // Set current_power_state to indicate that resume is called.
+ current_power_state_ = DevicePowerState::DEVICE_POWER_STATE_D0;
+ return ZX_OK;
+ }
void AddDeviceWithPowerArgs(::fidl::VectorView<DevicePowerStateInfo> info,
AddDeviceWithPowerArgsCompleter::Sync completer) override;
diff --git a/zircon/system/dev/test/ddk-power/test.cc b/zircon/system/dev/test/ddk-power/test.cc
index e755c2e..acd4b95 100644
--- a/zircon/system/dev/test/ddk-power/test.cc
+++ b/zircon/system/dev/test/ddk-power/test.cc
@@ -20,10 +20,10 @@
using llcpp::fuchsia::device::DevicePowerStateInfo;
using llcpp::fuchsia::device::MAX_DEVICE_POWER_STATES;
using llcpp::fuchsia::device::SystemPowerStateInfo;
-using llcpp::fuchsia::device::power::test::TestDevice;
+using llcpp::fuchsia::device::manager::Administrator;
using llcpp::fuchsia::device::manager::MAX_SYSTEM_POWER_STATES;
using llcpp::fuchsia::device::manager::SystemPowerState;
-using llcpp::fuchsia::device::manager::Administrator;
+using llcpp::fuchsia::device::power::test::TestDevice;
class PowerTestCase : public zxtest::Test {
public:
@@ -501,8 +501,8 @@
ASSERT_OK(fdio_service_connect_at(devmgr.svc_root_dir().get(), service_name, remote.release()));
ASSERT_NE(devmgr.svc_root_dir().get(), ZX_HANDLE_INVALID);
- auto suspend_result = Administrator::Call::Suspend(zx::unowned(local),
- ::llcpp::fuchsia::device::manager::SUSPEND_FLAG_REBOOT);
+ auto suspend_result = Administrator::Call::Suspend(
+ zx::unowned(local), ::llcpp::fuchsia::device::manager::SUSPEND_FLAG_REBOOT);
ASSERT_OK(suspend_result.status());
const auto &suspend_response = suspend_result.value();
ASSERT_OK(suspend_response.status);
@@ -531,3 +531,103 @@
ASSERT_EQ(parent_dev_suspend_response->result.response().cur_state,
DevicePowerState::DEVICE_POWER_STATE_D1);
}
+
+TEST_F(PowerTestCase, SystemResume) {
+ // Add Capabilities
+ DevicePowerStateInfo states[3];
+ states[0].state_id = DevicePowerState::DEVICE_POWER_STATE_D0;
+ states[0].is_supported = true;
+ states[0].restore_latency = 0;
+ states[1].state_id = DevicePowerState::DEVICE_POWER_STATE_D2;
+ states[1].is_supported = true;
+ states[1].restore_latency = 100;
+ states[2].state_id = DevicePowerState::DEVICE_POWER_STATE_D3COLD;
+ states[2].is_supported = true;
+ states[2].restore_latency = 1000;
+ AddChildWithPowerArgs(states, fbl::count_of(states));
+
+ ::fidl::Array<SystemPowerStateInfo, MAX_SYSTEM_POWER_STATES> mapping{};
+ for (size_t i = 0; i < MAX_SYSTEM_POWER_STATES; i++) {
+ mapping[i].dev_state = DevicePowerState::DEVICE_POWER_STATE_D2;
+ mapping[i].wakeup_enable = false;
+ }
+ mapping[static_cast<size_t>(SystemPowerState::SYSTEM_POWER_STATE_FULLY_ON)].dev_state =
+ DevicePowerState::DEVICE_POWER_STATE_D0;
+ auto update_result =
+ Controller::Call::UpdatePowerStateMapping(zx::unowned(child2_device_handle), mapping);
+ ASSERT_OK(update_result.status());
+ zx_status_t call_status = ZX_OK;
+ if (update_result->result.is_err()) {
+ call_status = update_result->result.err();
+ }
+ ASSERT_OK(call_status);
+
+ zx::channel local, remote;
+ ASSERT_OK(zx::channel::create(0, &local, &remote));
+
+ char service_name[100];
+ snprintf(service_name, sizeof(service_name), "svc/%s",
+ ::llcpp::fuchsia::device::manager::Administrator::Name);
+ ASSERT_OK(fdio_service_connect_at(devmgr.svc_root_dir().get(), service_name, remote.release()));
+ ASSERT_NE(devmgr.svc_root_dir().get(), ZX_HANDLE_INVALID);
+
+ auto suspend_result = Administrator::Call::Suspend(
+ zx::unowned(local), ::llcpp::fuchsia::device::manager::SUSPEND_FLAG_REBOOT);
+ ASSERT_OK(suspend_result.status());
+ const auto &suspend_response = suspend_result.value();
+ ASSERT_OK(suspend_response.status);
+
+ // Verify the child's DdkSuspendNew routine gets called.
+ auto child_dev_suspend_response =
+ TestDevice::Call::GetCurrentDevicePowerState(zx::unowned(child2_device_handle));
+ ASSERT_OK(child_dev_suspend_response.status());
+ call_status = ZX_OK;
+ if (child_dev_suspend_response->result.is_err()) {
+ call_status = child_dev_suspend_response->result.err();
+ }
+ ASSERT_OK(call_status);
+ ASSERT_EQ(child_dev_suspend_response->result.response().cur_state,
+ DevicePowerState::DEVICE_POWER_STATE_D2);
+
+ // Verify the parent'd DdkSuspend routine gets called.
+ auto parent_dev_suspend_response =
+ TestDevice::Call::GetCurrentDevicePowerState(zx::unowned(parent_device_handle));
+ ASSERT_OK(parent_dev_suspend_response.status());
+ call_status = ZX_OK;
+ if (parent_dev_suspend_response->result.is_err()) {
+ call_status = parent_dev_suspend_response->result.err();
+ }
+ ASSERT_OK(call_status);
+ ASSERT_EQ(parent_dev_suspend_response->result.response().cur_state,
+ DevicePowerState::DEVICE_POWER_STATE_D1);
+
+ auto resume_result = Administrator::Call::Resume(zx::unowned(local),
+ SystemPowerState::SYSTEM_POWER_STATE_FULLY_ON);
+ ASSERT_OK(resume_result.status());
+ const auto &resume_response = resume_result.value();
+ ASSERT_OK(resume_response.status);
+
+ // Verify the child's DdkResumeNew routine gets called.
+ auto child_dev_resume_response =
+ TestDevice::Call::GetCurrentDevicePowerState(zx::unowned(child2_device_handle));
+ ASSERT_OK(child_dev_resume_response.status());
+ call_status = ZX_OK;
+ if (child_dev_resume_response->result.is_err()) {
+ call_status = child_dev_resume_response->result.err();
+ }
+ ASSERT_OK(call_status);
+ ASSERT_EQ(child_dev_resume_response->result.response().cur_state,
+ DevicePowerState::DEVICE_POWER_STATE_D0);
+
+ // Verify the parent'd DdkSuspend routine gets called.
+ auto parent_dev_resume_response =
+ TestDevice::Call::GetCurrentDevicePowerState(zx::unowned(parent_device_handle));
+ ASSERT_OK(parent_dev_resume_response.status());
+ call_status = ZX_OK;
+ if (parent_dev_resume_response->result.is_err()) {
+ call_status = parent_dev_resume_response->result.err();
+ }
+ ASSERT_OK(call_status);
+ ASSERT_EQ(parent_dev_resume_response->result.response().cur_state,
+ DevicePowerState::DEVICE_POWER_STATE_D0);
+}
diff --git a/zircon/system/fidl/fuchsia-device-manager/administrator.fidl b/zircon/system/fidl/fuchsia-device-manager/administrator.fidl
index eb139b3..2df38db 100644
--- a/zircon/system/fidl/fuchsia-device-manager/administrator.fidl
+++ b/zircon/system/fidl/fuchsia-device-manager/administrator.fidl
@@ -18,14 +18,15 @@
// remove the suspend flags. For now, treat each suspend flag as a system
// power state.
enum SystemPowerState : uint8 {
- SYSTEM_POWER_STATE_REBOOT = 0;
- SYSTEM_POWER_STATE_REBOOT_BOOTLOADER = 1;
- SYSTEM_POWER_STATE_REBOOT_RECOVERY = 2;
- SYSTEM_POWER_STATE_POWEROFF = 3;
- SYSTEM_POWER_STATE_MEXEC = 4;
- SYSTEM_POWER_STATE_SUSPEND_RAM = 5;
+ SYSTEM_POWER_STATE_FULLY_ON = 0;
+ SYSTEM_POWER_STATE_REBOOT = 1;
+ SYSTEM_POWER_STATE_REBOOT_BOOTLOADER = 2;
+ SYSTEM_POWER_STATE_REBOOT_RECOVERY = 3;
+ SYSTEM_POWER_STATE_POWEROFF = 4;
+ SYSTEM_POWER_STATE_MEXEC = 5;
+ SYSTEM_POWER_STATE_SUSPEND_RAM = 6;
};
-const uint32 MAX_SYSTEM_POWER_STATES = 6;
+const uint32 MAX_SYSTEM_POWER_STATES = 7;
/// Provides administration services for the device manager service and the device tree it controls.
[Discoverable, Layout = "Simple"]
@@ -33,4 +34,6 @@
/// Ask all devices to enter the suspend state indicated by `flags`. Flags should be some
/// combination of `DEVICE_SUSPEND_FLAG_*` from the DDK.
Suspend(uint32 flags) -> (zx.status status);
+ /// Ask all devices to resume to active state indicated by the state.
+ Resume(SystemPowerState state) -> (zx.status status);
};
diff --git a/zircon/system/fidl/fuchsia-device-manager/coordinator.fidl b/zircon/system/fidl/fuchsia-device-manager/coordinator.fidl
index db4a8db..334a985 100644
--- a/zircon/system/fidl/fuchsia-device-manager/coordinator.fidl
+++ b/zircon/system/fidl/fuchsia-device-manager/coordinator.fidl
@@ -117,6 +117,10 @@
/// Ask devhost to suspend this device, using the target state indicated by `flags`.
Suspend(uint32 flags) -> (zx.status status);
+ /// Ask devhost to resume this device, using the target system state indicated by
+ //'target_system_state'.
+ Resume(uint32 target_system_state) -> (zx.status status);
+
/// Inform devhost about the compatibility test status when compatibility tests
/// fail or complete successfully.
// TODO(ravoorir) : This should be an asynchronous call from devhost to
diff --git a/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/fidl.cc b/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/fidl.cc
index 32c7cce..4c89533 100644
--- a/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/fidl.cc
+++ b/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/fidl.cc
@@ -391,6 +391,12 @@
constexpr uint64_t kAdministrator_Suspend_GenOrdinal = 0x4bb44c32133da26elu;
extern "C" const fidl_type_t fuchsia_device_manager_AdministratorSuspendRequestTable;
extern "C" const fidl_type_t fuchsia_device_manager_AdministratorSuspendResponseTable;
+[[maybe_unused]]
+constexpr uint64_t kAdministrator_Resume_Ordinal = 0x3f61f33b00000000lu;
+[[maybe_unused]]
+constexpr uint64_t kAdministrator_Resume_GenOrdinal = 0x7e953b4960a4cbaelu;
+extern "C" const fidl_type_t fuchsia_device_manager_AdministratorResumeRequestTable;
+extern "C" const fidl_type_t fuchsia_device_manager_AdministratorResumeResponseTable;
} // namespace
template <>
@@ -456,6 +462,69 @@
return ::fidl::Decode(std::move(_call_result.message));
}
+template <>
+Administrator::ResultOf::Resume_Impl<Administrator::ResumeResponse>::Resume_Impl(zx::unowned_channel _client_end, SystemPowerState state) {
+ constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ResumeRequest, ::fidl::MessageDirection::kSending>();
+ ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
+ auto& _write_bytes_array = _write_bytes_inlined;
+ uint8_t* _write_bytes = _write_bytes_array.view().data();
+ memset(_write_bytes, 0, ResumeRequest::PrimarySize);
+ auto& _request = *reinterpret_cast<ResumeRequest*>(_write_bytes);
+ _request.state = std::move(state);
+ ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(ResumeRequest));
+ ::fidl::DecodedMessage<ResumeRequest> _decoded_request(std::move(_request_bytes));
+ Super::SetResult(
+ Administrator::InPlace::Resume(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
+}
+
+Administrator::ResultOf::Resume Administrator::SyncClient::Resume(SystemPowerState state) {
+ return ResultOf::Resume(zx::unowned_channel(this->channel_), std::move(state));
+}
+
+Administrator::ResultOf::Resume Administrator::Call::Resume(zx::unowned_channel _client_end, SystemPowerState state) {
+ return ResultOf::Resume(std::move(_client_end), std::move(state));
+}
+
+template <>
+Administrator::UnownedResultOf::Resume_Impl<Administrator::ResumeResponse>::Resume_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, SystemPowerState state, ::fidl::BytePart _response_buffer) {
+ if (_request_buffer.capacity() < ResumeRequest::PrimarySize) {
+ Super::SetFailure(::fidl::DecodeResult<ResumeResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
+ return;
+ }
+ memset(_request_buffer.data(), 0, ResumeRequest::PrimarySize);
+ auto& _request = *reinterpret_cast<ResumeRequest*>(_request_buffer.data());
+ _request.state = std::move(state);
+ _request_buffer.set_actual(sizeof(ResumeRequest));
+ ::fidl::DecodedMessage<ResumeRequest> _decoded_request(std::move(_request_buffer));
+ Super::SetResult(
+ Administrator::InPlace::Resume(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
+}
+
+Administrator::UnownedResultOf::Resume Administrator::SyncClient::Resume(::fidl::BytePart _request_buffer, SystemPowerState state, ::fidl::BytePart _response_buffer) {
+ return UnownedResultOf::Resume(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(state), std::move(_response_buffer));
+}
+
+Administrator::UnownedResultOf::Resume Administrator::Call::Resume(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, SystemPowerState state, ::fidl::BytePart _response_buffer) {
+ return UnownedResultOf::Resume(std::move(_client_end), std::move(_request_buffer), std::move(state), std::move(_response_buffer));
+}
+
+::fidl::DecodeResult<Administrator::ResumeResponse> Administrator::InPlace::Resume(zx::unowned_channel _client_end, ::fidl::DecodedMessage<ResumeRequest> params, ::fidl::BytePart response_buffer) {
+ params.message()->_hdr = {};
+ params.message()->_hdr.ordinal = kAdministrator_Resume_Ordinal;
+ auto _encode_request_result = ::fidl::Encode(std::move(params));
+ if (_encode_request_result.status != ZX_OK) {
+ return ::fidl::DecodeResult<Administrator::ResumeResponse>::FromFailure(
+ std::move(_encode_request_result));
+ }
+ auto _call_result = ::fidl::Call<ResumeRequest, ResumeResponse>(
+ std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
+ if (_call_result.status != ZX_OK) {
+ return ::fidl::DecodeResult<Administrator::ResumeResponse>::FromFailure(
+ std::move(_call_result));
+ }
+ return ::fidl::Decode(std::move(_call_result.message));
+}
+
bool Administrator::TryDispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
if (msg->num_bytes < sizeof(fidl_message_header_t)) {
@@ -478,6 +547,19 @@
Interface::SuspendCompleter::Sync(txn));
return true;
}
+ case kAdministrator_Resume_Ordinal:
+ case kAdministrator_Resume_GenOrdinal:
+ {
+ auto result = ::fidl::DecodeAs<ResumeRequest>(msg);
+ if (result.status != ZX_OK) {
+ txn->Close(ZX_ERR_INVALID_ARGS);
+ return true;
+ }
+ auto message = result.message.message();
+ impl->Resume(std::move(message->state),
+ Interface::ResumeCompleter::Sync(txn));
+ return true;
+ }
default: {
return false;
}
@@ -523,6 +605,35 @@
}
+void Administrator::Interface::ResumeCompleterBase::Reply(int32_t status) {
+ constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ResumeResponse, ::fidl::MessageDirection::kSending>();
+ FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
+ auto& _response = *reinterpret_cast<ResumeResponse*>(_write_bytes);
+ _response._hdr.ordinal = kAdministrator_Resume_Ordinal;
+ _response.status = std::move(status);
+ ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(ResumeResponse));
+ CompleterBase::SendReply(::fidl::DecodedMessage<ResumeResponse>(std::move(_response_bytes)));
+}
+
+void Administrator::Interface::ResumeCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
+ if (_buffer.capacity() < ResumeResponse::PrimarySize) {
+ CompleterBase::Close(ZX_ERR_INTERNAL);
+ return;
+ }
+ auto& _response = *reinterpret_cast<ResumeResponse*>(_buffer.data());
+ _response._hdr.ordinal = kAdministrator_Resume_Ordinal;
+ _response.status = std::move(status);
+ _buffer.set_actual(sizeof(ResumeResponse));
+ CompleterBase::SendReply(::fidl::DecodedMessage<ResumeResponse>(std::move(_buffer)));
+}
+
+void Administrator::Interface::ResumeCompleterBase::Reply(::fidl::DecodedMessage<ResumeResponse> params) {
+ params.message()->_hdr = {};
+ params.message()->_hdr.ordinal = kAdministrator_Resume_Ordinal;
+ CompleterBase::SendReply(std::move(params));
+}
+
+
namespace {
[[maybe_unused]]
@@ -1774,6 +1885,12 @@
extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerSuspendRequestTable;
extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerSuspendResponseTable;
[[maybe_unused]]
+constexpr uint64_t kDeviceController_Resume_Ordinal = 0x4d69ba3300000000lu;
+[[maybe_unused]]
+constexpr uint64_t kDeviceController_Resume_GenOrdinal = 0x4f111286b7bd9caflu;
+extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerResumeRequestTable;
+extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerResumeResponseTable;
+[[maybe_unused]]
constexpr uint64_t kDeviceController_CompleteCompatibilityTests_Ordinal = 0x475e367c00000000lu;
[[maybe_unused]]
constexpr uint64_t kDeviceController_CompleteCompatibilityTests_GenOrdinal = 0x3883342451945549lu;
@@ -2106,6 +2223,69 @@
return ::fidl::Decode(std::move(_call_result.message));
}
+template <>
+DeviceController::ResultOf::Resume_Impl<DeviceController::ResumeResponse>::Resume_Impl(zx::unowned_channel _client_end, uint32_t target_system_state) {
+ constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ResumeRequest, ::fidl::MessageDirection::kSending>();
+ ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
+ auto& _write_bytes_array = _write_bytes_inlined;
+ uint8_t* _write_bytes = _write_bytes_array.view().data();
+ memset(_write_bytes, 0, ResumeRequest::PrimarySize);
+ auto& _request = *reinterpret_cast<ResumeRequest*>(_write_bytes);
+ _request.target_system_state = std::move(target_system_state);
+ ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(ResumeRequest));
+ ::fidl::DecodedMessage<ResumeRequest> _decoded_request(std::move(_request_bytes));
+ Super::SetResult(
+ DeviceController::InPlace::Resume(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
+}
+
+DeviceController::ResultOf::Resume DeviceController::SyncClient::Resume(uint32_t target_system_state) {
+ return ResultOf::Resume(zx::unowned_channel(this->channel_), std::move(target_system_state));
+}
+
+DeviceController::ResultOf::Resume DeviceController::Call::Resume(zx::unowned_channel _client_end, uint32_t target_system_state) {
+ return ResultOf::Resume(std::move(_client_end), std::move(target_system_state));
+}
+
+template <>
+DeviceController::UnownedResultOf::Resume_Impl<DeviceController::ResumeResponse>::Resume_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t target_system_state, ::fidl::BytePart _response_buffer) {
+ if (_request_buffer.capacity() < ResumeRequest::PrimarySize) {
+ Super::SetFailure(::fidl::DecodeResult<ResumeResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
+ return;
+ }
+ memset(_request_buffer.data(), 0, ResumeRequest::PrimarySize);
+ auto& _request = *reinterpret_cast<ResumeRequest*>(_request_buffer.data());
+ _request.target_system_state = std::move(target_system_state);
+ _request_buffer.set_actual(sizeof(ResumeRequest));
+ ::fidl::DecodedMessage<ResumeRequest> _decoded_request(std::move(_request_buffer));
+ Super::SetResult(
+ DeviceController::InPlace::Resume(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
+}
+
+DeviceController::UnownedResultOf::Resume DeviceController::SyncClient::Resume(::fidl::BytePart _request_buffer, uint32_t target_system_state, ::fidl::BytePart _response_buffer) {
+ return UnownedResultOf::Resume(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(target_system_state), std::move(_response_buffer));
+}
+
+DeviceController::UnownedResultOf::Resume DeviceController::Call::Resume(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t target_system_state, ::fidl::BytePart _response_buffer) {
+ return UnownedResultOf::Resume(std::move(_client_end), std::move(_request_buffer), std::move(target_system_state), std::move(_response_buffer));
+}
+
+::fidl::DecodeResult<DeviceController::ResumeResponse> DeviceController::InPlace::Resume(zx::unowned_channel _client_end, ::fidl::DecodedMessage<ResumeRequest> params, ::fidl::BytePart response_buffer) {
+ params.message()->_hdr = {};
+ params.message()->_hdr.ordinal = kDeviceController_Resume_Ordinal;
+ auto _encode_request_result = ::fidl::Encode(std::move(params));
+ if (_encode_request_result.status != ZX_OK) {
+ return ::fidl::DecodeResult<DeviceController::ResumeResponse>::FromFailure(
+ std::move(_encode_request_result));
+ }
+ auto _call_result = ::fidl::Call<ResumeRequest, ResumeResponse>(
+ std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
+ if (_call_result.status != ZX_OK) {
+ return ::fidl::DecodeResult<DeviceController::ResumeResponse>::FromFailure(
+ std::move(_call_result));
+ }
+ return ::fidl::Decode(std::move(_call_result.message));
+}
+
DeviceController::ResultOf::CompleteCompatibilityTests_Impl::CompleteCompatibilityTests_Impl(zx::unowned_channel _client_end, CompatibilityTestStatus status) {
constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<CompleteCompatibilityTestsRequest, ::fidl::MessageDirection::kSending>();
@@ -2254,6 +2434,19 @@
Interface::SuspendCompleter::Sync(txn));
return true;
}
+ case kDeviceController_Resume_Ordinal:
+ case kDeviceController_Resume_GenOrdinal:
+ {
+ auto result = ::fidl::DecodeAs<ResumeRequest>(msg);
+ if (result.status != ZX_OK) {
+ txn->Close(ZX_ERR_INVALID_ARGS);
+ return true;
+ }
+ auto message = result.message.message();
+ impl->Resume(std::move(message->target_system_state),
+ Interface::ResumeCompleter::Sync(txn));
+ return true;
+ }
case kDeviceController_CompleteCompatibilityTests_Ordinal:
case kDeviceController_CompleteCompatibilityTests_GenOrdinal:
{
@@ -2343,6 +2536,35 @@
}
+void DeviceController::Interface::ResumeCompleterBase::Reply(int32_t status) {
+ constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ResumeResponse, ::fidl::MessageDirection::kSending>();
+ FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
+ auto& _response = *reinterpret_cast<ResumeResponse*>(_write_bytes);
+ _response._hdr.ordinal = kDeviceController_Resume_Ordinal;
+ _response.status = std::move(status);
+ ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(ResumeResponse));
+ CompleterBase::SendReply(::fidl::DecodedMessage<ResumeResponse>(std::move(_response_bytes)));
+}
+
+void DeviceController::Interface::ResumeCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
+ if (_buffer.capacity() < ResumeResponse::PrimarySize) {
+ CompleterBase::Close(ZX_ERR_INTERNAL);
+ return;
+ }
+ auto& _response = *reinterpret_cast<ResumeResponse*>(_buffer.data());
+ _response._hdr.ordinal = kDeviceController_Resume_Ordinal;
+ _response.status = std::move(status);
+ _buffer.set_actual(sizeof(ResumeResponse));
+ CompleterBase::SendReply(::fidl::DecodedMessage<ResumeResponse>(std::move(_buffer)));
+}
+
+void DeviceController::Interface::ResumeCompleterBase::Reply(::fidl::DecodedMessage<ResumeResponse> params) {
+ params.message()->_hdr = {};
+ params.message()->_hdr.ordinal = kDeviceController_Resume_Ordinal;
+ CompleterBase::SendReply(std::move(params));
+}
+
+
namespace {
[[maybe_unused]]
diff --git a/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/include/fuchsia/device/manager/llcpp/fidl.h b/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/include/fuchsia/device/manager/llcpp/fidl.h
index 6ecb49e..e9f77b8 100644
--- a/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/include/fuchsia/device/manager/llcpp/fidl.h
+++ b/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/include/fuchsia/device/manager/llcpp/fidl.h
@@ -23,12 +23,13 @@
namespace manager {
enum class SystemPowerState : uint8_t {
- SYSTEM_POWER_STATE_REBOOT = 0u,
- SYSTEM_POWER_STATE_REBOOT_BOOTLOADER = 1u,
- SYSTEM_POWER_STATE_REBOOT_RECOVERY = 2u,
- SYSTEM_POWER_STATE_POWEROFF = 3u,
- SYSTEM_POWER_STATE_MEXEC = 4u,
- SYSTEM_POWER_STATE_SUSPEND_RAM = 5u,
+ SYSTEM_POWER_STATE_FULLY_ON = 0u,
+ SYSTEM_POWER_STATE_REBOOT = 1u,
+ SYSTEM_POWER_STATE_REBOOT_BOOTLOADER = 2u,
+ SYSTEM_POWER_STATE_REBOOT_RECOVERY = 3u,
+ SYSTEM_POWER_STATE_POWEROFF = 4u,
+ SYSTEM_POWER_STATE_MEXEC = 5u,
+ SYSTEM_POWER_STATE_SUSPEND_RAM = 6u,
};
@@ -532,6 +533,8 @@
extern "C" const fidl_type_t fuchsia_device_manager_AdministratorSuspendRequestTable;
extern "C" const fidl_type_t fuchsia_device_manager_AdministratorSuspendResponseTable;
+extern "C" const fidl_type_t fuchsia_device_manager_AdministratorResumeRequestTable;
+extern "C" const fidl_type_t fuchsia_device_manager_AdministratorResumeResponseTable;
// Provides administration services for the device manager service and the device tree it controls.
class Administrator final {
@@ -567,6 +570,34 @@
using ResponseType = SuspendResponse;
};
+ struct ResumeResponse final {
+ FIDL_ALIGNDECL
+ fidl_message_header_t _hdr;
+ int32_t status;
+
+ static constexpr const fidl_type_t* Type = &fuchsia_device_manager_AdministratorResumeResponseTable;
+ static constexpr uint32_t MaxNumHandles = 0;
+ static constexpr uint32_t PrimarySize = 24;
+ static constexpr uint32_t MaxOutOfLine = 0;
+ static constexpr bool HasFlexibleEnvelope = false;
+ static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
+ ::fidl::internal::TransactionalMessageKind::kResponse;
+ };
+ struct ResumeRequest final {
+ FIDL_ALIGNDECL
+ fidl_message_header_t _hdr;
+ SystemPowerState state;
+
+ static constexpr const fidl_type_t* Type = &fuchsia_device_manager_AdministratorResumeRequestTable;
+ static constexpr uint32_t MaxNumHandles = 0;
+ static constexpr uint32_t PrimarySize = 24;
+ static constexpr uint32_t MaxOutOfLine = 0;
+ static constexpr bool HasFlexibleEnvelope = false;
+ static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
+ ::fidl::internal::TransactionalMessageKind::kRequest;
+ using ResponseType = ResumeResponse;
+ };
+
// Collection of return types of FIDL calls in this interface.
class ResultOf final {
@@ -588,9 +619,26 @@
using Super::operator->;
using Super::operator*;
};
+ template <typename ResponseType>
+ class Resume_Impl final : private ::fidl::internal::OwnedSyncCallBase<ResponseType> {
+ using Super = ::fidl::internal::OwnedSyncCallBase<ResponseType>;
+ public:
+ Resume_Impl(zx::unowned_channel _client_end, SystemPowerState state);
+ ~Resume_Impl() = default;
+ Resume_Impl(Resume_Impl&& other) = default;
+ Resume_Impl& operator=(Resume_Impl&& other) = default;
+ using Super::status;
+ using Super::error;
+ using Super::ok;
+ using Super::Unwrap;
+ using Super::value;
+ using Super::operator->;
+ using Super::operator*;
+ };
public:
using Suspend = Suspend_Impl<SuspendResponse>;
+ using Resume = Resume_Impl<ResumeResponse>;
};
// Collection of return types of FIDL calls in this interface,
@@ -614,9 +662,26 @@
using Super::operator->;
using Super::operator*;
};
+ template <typename ResponseType>
+ class Resume_Impl final : private ::fidl::internal::UnownedSyncCallBase<ResponseType> {
+ using Super = ::fidl::internal::UnownedSyncCallBase<ResponseType>;
+ public:
+ Resume_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, SystemPowerState state, ::fidl::BytePart _response_buffer);
+ ~Resume_Impl() = default;
+ Resume_Impl(Resume_Impl&& other) = default;
+ Resume_Impl& operator=(Resume_Impl&& other) = default;
+ using Super::status;
+ using Super::error;
+ using Super::ok;
+ using Super::Unwrap;
+ using Super::value;
+ using Super::operator->;
+ using Super::operator*;
+ };
public:
using Suspend = Suspend_Impl<SuspendResponse>;
+ using Resume = Resume_Impl<ResumeResponse>;
};
class SyncClient final {
@@ -640,6 +705,14 @@
// Caller provides the backing storage for FIDL message via request and response buffers.
UnownedResultOf::Suspend Suspend(::fidl::BytePart _request_buffer, uint32_t flags, ::fidl::BytePart _response_buffer);
+ // Ask all devices to resume to active state indicated by the state.
+ // Allocates 48 bytes of message buffer on the stack. No heap allocation necessary.
+ ResultOf::Resume Resume(SystemPowerState state);
+
+ // Ask all devices to resume to active state indicated by the state.
+ // Caller provides the backing storage for FIDL message via request and response buffers.
+ UnownedResultOf::Resume Resume(::fidl::BytePart _request_buffer, SystemPowerState state, ::fidl::BytePart _response_buffer);
+
private:
::zx::channel channel_;
};
@@ -659,6 +732,14 @@
// Caller provides the backing storage for FIDL message via request and response buffers.
static UnownedResultOf::Suspend Suspend(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t flags, ::fidl::BytePart _response_buffer);
+ // Ask all devices to resume to active state indicated by the state.
+ // Allocates 48 bytes of message buffer on the stack. No heap allocation necessary.
+ static ResultOf::Resume Resume(zx::unowned_channel _client_end, SystemPowerState state);
+
+ // Ask all devices to resume to active state indicated by the state.
+ // Caller provides the backing storage for FIDL message via request and response buffers.
+ static UnownedResultOf::Resume Resume(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, SystemPowerState state, ::fidl::BytePart _response_buffer);
+
};
// Messages are encoded and decoded in-place when these methods are used.
@@ -671,6 +752,9 @@
// combination of `DEVICE_SUSPEND_FLAG_*` from the DDK.
static ::fidl::DecodeResult<SuspendResponse> Suspend(zx::unowned_channel _client_end, ::fidl::DecodedMessage<SuspendRequest> params, ::fidl::BytePart response_buffer);
+ // Ask all devices to resume to active state indicated by the state.
+ static ::fidl::DecodeResult<ResumeResponse> Resume(zx::unowned_channel _client_end, ::fidl::DecodedMessage<ResumeRequest> params, ::fidl::BytePart response_buffer);
+
};
// Pure-virtual interface to be implemented by a server.
@@ -695,6 +779,20 @@
virtual void Suspend(uint32_t flags, SuspendCompleter::Sync _completer) = 0;
+ class ResumeCompleterBase : public _Base {
+ public:
+ void Reply(int32_t status);
+ void Reply(::fidl::BytePart _buffer, int32_t status);
+ void Reply(::fidl::DecodedMessage<ResumeResponse> params);
+
+ protected:
+ using ::fidl::CompleterBase::CompleterBase;
+ };
+
+ using ResumeCompleter = ::fidl::Completer<ResumeCompleterBase>;
+
+ virtual void Resume(SystemPowerState state, ResumeCompleter::Sync _completer) = 0;
+
};
// Attempts to dispatch the incoming message to a handler function in the server implementation.
@@ -736,7 +834,7 @@
// Maximum number of bytes in a metadata payload
constexpr uint32_t METADATA_MAX = 8192u;
-constexpr uint32_t MAX_SYSTEM_POWER_STATES = 6u;
+constexpr uint32_t MAX_SYSTEM_POWER_STATES = 7u;
extern "C" const fidl_type_t fuchsia_device_manager_DevhostControllerCreateDeviceStubRequestTable;
extern "C" const fidl_type_t fuchsia_device_manager_DevhostControllerCreateDeviceRequestTable;
@@ -2790,6 +2888,8 @@
extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerConnectProxyRequestTable;
extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerSuspendRequestTable;
extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerSuspendResponseTable;
+extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerResumeRequestTable;
+extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerResumeResponseTable;
extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerCompleteCompatibilityTestsRequestTable;
// Protocol for controlling devices in a devhost process from the devcoordinator
@@ -2875,6 +2975,34 @@
using ResponseType = SuspendResponse;
};
+ struct ResumeResponse final {
+ FIDL_ALIGNDECL
+ fidl_message_header_t _hdr;
+ int32_t status;
+
+ static constexpr const fidl_type_t* Type = &fuchsia_device_manager_DeviceControllerResumeResponseTable;
+ static constexpr uint32_t MaxNumHandles = 0;
+ static constexpr uint32_t PrimarySize = 24;
+ static constexpr uint32_t MaxOutOfLine = 0;
+ static constexpr bool HasFlexibleEnvelope = false;
+ static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
+ ::fidl::internal::TransactionalMessageKind::kResponse;
+ };
+ struct ResumeRequest final {
+ FIDL_ALIGNDECL
+ fidl_message_header_t _hdr;
+ uint32_t target_system_state;
+
+ static constexpr const fidl_type_t* Type = &fuchsia_device_manager_DeviceControllerResumeRequestTable;
+ static constexpr uint32_t MaxNumHandles = 0;
+ static constexpr uint32_t PrimarySize = 24;
+ static constexpr uint32_t MaxOutOfLine = 0;
+ static constexpr bool HasFlexibleEnvelope = false;
+ static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
+ ::fidl::internal::TransactionalMessageKind::kRequest;
+ using ResponseType = ResumeResponse;
+ };
+
struct CompleteCompatibilityTestsRequest final {
FIDL_ALIGNDECL
fidl_message_header_t _hdr;
@@ -2970,6 +3098,22 @@
using Super::operator->;
using Super::operator*;
};
+ template <typename ResponseType>
+ class Resume_Impl final : private ::fidl::internal::OwnedSyncCallBase<ResponseType> {
+ using Super = ::fidl::internal::OwnedSyncCallBase<ResponseType>;
+ public:
+ Resume_Impl(zx::unowned_channel _client_end, uint32_t target_system_state);
+ ~Resume_Impl() = default;
+ Resume_Impl(Resume_Impl&& other) = default;
+ Resume_Impl& operator=(Resume_Impl&& other) = default;
+ using Super::status;
+ using Super::error;
+ using Super::ok;
+ using Super::Unwrap;
+ using Super::value;
+ using Super::operator->;
+ using Super::operator*;
+ };
class CompleteCompatibilityTests_Impl final : private ::fidl::internal::StatusAndError {
using Super = ::fidl::internal::StatusAndError;
public:
@@ -2989,6 +3133,7 @@
using CompleteRemoval = CompleteRemoval_Impl;
using RemoveDevice = RemoveDevice_Impl;
using Suspend = Suspend_Impl<SuspendResponse>;
+ using Resume = Resume_Impl<ResumeResponse>;
using CompleteCompatibilityTests = CompleteCompatibilityTests_Impl;
};
@@ -3073,6 +3218,22 @@
using Super::operator->;
using Super::operator*;
};
+ template <typename ResponseType>
+ class Resume_Impl final : private ::fidl::internal::UnownedSyncCallBase<ResponseType> {
+ using Super = ::fidl::internal::UnownedSyncCallBase<ResponseType>;
+ public:
+ Resume_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t target_system_state, ::fidl::BytePart _response_buffer);
+ ~Resume_Impl() = default;
+ Resume_Impl(Resume_Impl&& other) = default;
+ Resume_Impl& operator=(Resume_Impl&& other) = default;
+ using Super::status;
+ using Super::error;
+ using Super::ok;
+ using Super::Unwrap;
+ using Super::value;
+ using Super::operator->;
+ using Super::operator*;
+ };
class CompleteCompatibilityTests_Impl final : private ::fidl::internal::StatusAndError {
using Super = ::fidl::internal::StatusAndError;
public:
@@ -3092,6 +3253,7 @@
using CompleteRemoval = CompleteRemoval_Impl;
using RemoveDevice = RemoveDevice_Impl;
using Suspend = Suspend_Impl<SuspendResponse>;
+ using Resume = Resume_Impl<ResumeResponse>;
using CompleteCompatibilityTests = CompleteCompatibilityTests_Impl;
};
@@ -3159,6 +3321,14 @@
// Caller provides the backing storage for FIDL message via request and response buffers.
UnownedResultOf::Suspend Suspend(::fidl::BytePart _request_buffer, uint32_t flags, ::fidl::BytePart _response_buffer);
+ // Ask devhost to resume this device, using the target system state indicated by
+ // Allocates 48 bytes of message buffer on the stack. No heap allocation necessary.
+ ResultOf::Resume Resume(uint32_t target_system_state);
+
+ // Ask devhost to resume this device, using the target system state indicated by
+ // Caller provides the backing storage for FIDL message via request and response buffers.
+ UnownedResultOf::Resume Resume(::fidl::BytePart _request_buffer, uint32_t target_system_state, ::fidl::BytePart _response_buffer);
+
// Inform devhost about the compatibility test status when compatibility tests
// fail or complete successfully.
// Allocates 24 bytes of message buffer on the stack. No heap allocation necessary.
@@ -3231,6 +3401,14 @@
// Caller provides the backing storage for FIDL message via request and response buffers.
static UnownedResultOf::Suspend Suspend(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t flags, ::fidl::BytePart _response_buffer);
+ // Ask devhost to resume this device, using the target system state indicated by
+ // Allocates 48 bytes of message buffer on the stack. No heap allocation necessary.
+ static ResultOf::Resume Resume(zx::unowned_channel _client_end, uint32_t target_system_state);
+
+ // Ask devhost to resume this device, using the target system state indicated by
+ // Caller provides the backing storage for FIDL message via request and response buffers.
+ static UnownedResultOf::Resume Resume(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t target_system_state, ::fidl::BytePart _response_buffer);
+
// Inform devhost about the compatibility test status when compatibility tests
// fail or complete successfully.
// Allocates 24 bytes of message buffer on the stack. No heap allocation necessary.
@@ -3276,6 +3454,9 @@
// Ask devhost to suspend this device, using the target state indicated by `flags`.
static ::fidl::DecodeResult<SuspendResponse> Suspend(zx::unowned_channel _client_end, ::fidl::DecodedMessage<SuspendRequest> params, ::fidl::BytePart response_buffer);
+ // Ask devhost to resume this device, using the target system state indicated by
+ static ::fidl::DecodeResult<ResumeResponse> Resume(zx::unowned_channel _client_end, ::fidl::DecodedMessage<ResumeRequest> params, ::fidl::BytePart response_buffer);
+
// Inform devhost about the compatibility test status when compatibility tests
// fail or complete successfully.
static ::fidl::internal::StatusAndError CompleteCompatibilityTests(zx::unowned_channel _client_end, ::fidl::DecodedMessage<CompleteCompatibilityTestsRequest> params);
@@ -3334,6 +3515,20 @@
virtual void Suspend(uint32_t flags, SuspendCompleter::Sync _completer) = 0;
+ class ResumeCompleterBase : public _Base {
+ public:
+ void Reply(int32_t status);
+ void Reply(::fidl::BytePart _buffer, int32_t status);
+ void Reply(::fidl::DecodedMessage<ResumeResponse> params);
+
+ protected:
+ using ::fidl::CompleterBase::CompleterBase;
+ };
+
+ using ResumeCompleter = ::fidl::Completer<ResumeCompleterBase>;
+
+ virtual void Resume(uint32_t target_system_state, ResumeCompleter::Sync _completer) = 0;
+
using CompleteCompatibilityTestsCompleter = ::fidl::Completer<>;
virtual void CompleteCompatibilityTests(CompatibilityTestStatus status, CompleteCompatibilityTestsCompleter::Sync _completer) = 0;
@@ -5255,6 +5450,22 @@
static_assert(offsetof(::llcpp::fuchsia::device::manager::Administrator::SuspendResponse, status) == 16);
template <>
+struct IsFidlType<::llcpp::fuchsia::device::manager::Administrator::ResumeRequest> : public std::true_type {};
+template <>
+struct IsFidlMessage<::llcpp::fuchsia::device::manager::Administrator::ResumeRequest> : public std::true_type {};
+static_assert(sizeof(::llcpp::fuchsia::device::manager::Administrator::ResumeRequest)
+ == ::llcpp::fuchsia::device::manager::Administrator::ResumeRequest::PrimarySize);
+static_assert(offsetof(::llcpp::fuchsia::device::manager::Administrator::ResumeRequest, state) == 16);
+
+template <>
+struct IsFidlType<::llcpp::fuchsia::device::manager::Administrator::ResumeResponse> : public std::true_type {};
+template <>
+struct IsFidlMessage<::llcpp::fuchsia::device::manager::Administrator::ResumeResponse> : public std::true_type {};
+static_assert(sizeof(::llcpp::fuchsia::device::manager::Administrator::ResumeResponse)
+ == ::llcpp::fuchsia::device::manager::Administrator::ResumeResponse::PrimarySize);
+static_assert(offsetof(::llcpp::fuchsia::device::manager::Administrator::ResumeResponse, status) == 16);
+
+template <>
struct IsFidlType<::llcpp::fuchsia::device::manager::DevhostController::CreateDeviceStubRequest> : public std::true_type {};
template <>
struct IsFidlMessage<::llcpp::fuchsia::device::manager::DevhostController::CreateDeviceStubRequest> : public std::true_type {};
@@ -5490,6 +5701,22 @@
static_assert(offsetof(::llcpp::fuchsia::device::manager::DeviceController::SuspendResponse, status) == 16);
template <>
+struct IsFidlType<::llcpp::fuchsia::device::manager::DeviceController::ResumeRequest> : public std::true_type {};
+template <>
+struct IsFidlMessage<::llcpp::fuchsia::device::manager::DeviceController::ResumeRequest> : public std::true_type {};
+static_assert(sizeof(::llcpp::fuchsia::device::manager::DeviceController::ResumeRequest)
+ == ::llcpp::fuchsia::device::manager::DeviceController::ResumeRequest::PrimarySize);
+static_assert(offsetof(::llcpp::fuchsia::device::manager::DeviceController::ResumeRequest, target_system_state) == 16);
+
+template <>
+struct IsFidlType<::llcpp::fuchsia::device::manager::DeviceController::ResumeResponse> : public std::true_type {};
+template <>
+struct IsFidlMessage<::llcpp::fuchsia::device::manager::DeviceController::ResumeResponse> : public std::true_type {};
+static_assert(sizeof(::llcpp::fuchsia::device::manager::DeviceController::ResumeResponse)
+ == ::llcpp::fuchsia::device::manager::DeviceController::ResumeResponse::PrimarySize);
+static_assert(offsetof(::llcpp::fuchsia::device::manager::DeviceController::ResumeResponse, status) == 16);
+
+template <>
struct IsFidlType<::llcpp::fuchsia::device::manager::DeviceController::CompleteCompatibilityTestsRequest> : public std::true_type {};
template <>
struct IsFidlMessage<::llcpp::fuchsia::device::manager::DeviceController::CompleteCompatibilityTestsRequest> : public std::true_type {};
diff --git a/zircon/system/fidl/fuchsia-device/gen/llcpp/fidl.cc b/zircon/system/fidl/fuchsia-device/gen/llcpp/fidl.cc
index 361cecd..da936967 100644
--- a/zircon/system/fidl/fuchsia-device/gen/llcpp/fidl.cc
+++ b/zircon/system/fidl/fuchsia-device/gen/llcpp/fidl.cc
@@ -1307,7 +1307,7 @@
}
template <>
-Controller::ResultOf::UpdatePowerStateMapping_Impl<Controller::UpdatePowerStateMappingResponse>::UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 6> mapping) {
+Controller::ResultOf::UpdatePowerStateMapping_Impl<Controller::UpdatePowerStateMappingResponse>::UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 7> mapping) {
constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<UpdatePowerStateMappingRequest, ::fidl::MessageDirection::kSending>();
::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
auto& _write_bytes_array = _write_bytes_inlined;
@@ -1321,16 +1321,16 @@
Controller::InPlace::UpdatePowerStateMapping(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
}
-Controller::ResultOf::UpdatePowerStateMapping Controller::SyncClient::UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 6> mapping) {
+Controller::ResultOf::UpdatePowerStateMapping Controller::SyncClient::UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 7> mapping) {
return ResultOf::UpdatePowerStateMapping(zx::unowned_channel(this->channel_), std::move(mapping));
}
-Controller::ResultOf::UpdatePowerStateMapping Controller::Call::UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 6> mapping) {
+Controller::ResultOf::UpdatePowerStateMapping Controller::Call::UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 7> mapping) {
return ResultOf::UpdatePowerStateMapping(std::move(_client_end), std::move(mapping));
}
template <>
-Controller::UnownedResultOf::UpdatePowerStateMapping_Impl<Controller::UpdatePowerStateMappingResponse>::UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping, ::fidl::BytePart _response_buffer) {
+Controller::UnownedResultOf::UpdatePowerStateMapping_Impl<Controller::UpdatePowerStateMappingResponse>::UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer) {
if (_request_buffer.capacity() < UpdatePowerStateMappingRequest::PrimarySize) {
Super::SetFailure(::fidl::DecodeResult<UpdatePowerStateMappingResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
return;
@@ -1344,11 +1344,11 @@
Controller::InPlace::UpdatePowerStateMapping(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
}
-Controller::UnownedResultOf::UpdatePowerStateMapping Controller::SyncClient::UpdatePowerStateMapping(::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping, ::fidl::BytePart _response_buffer) {
+Controller::UnownedResultOf::UpdatePowerStateMapping Controller::SyncClient::UpdatePowerStateMapping(::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer) {
return UnownedResultOf::UpdatePowerStateMapping(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(mapping), std::move(_response_buffer));
}
-Controller::UnownedResultOf::UpdatePowerStateMapping Controller::Call::UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping, ::fidl::BytePart _response_buffer) {
+Controller::UnownedResultOf::UpdatePowerStateMapping Controller::Call::UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer) {
return UnownedResultOf::UpdatePowerStateMapping(std::move(_client_end), std::move(_request_buffer), std::move(mapping), std::move(_response_buffer));
}
@@ -2230,7 +2230,7 @@
::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetPowerStateMappingResponse));
CompleterBase::SendReply(::fidl::DecodedMessage<GetPowerStateMappingResponse>(std::move(_response_bytes)));
}
-void Controller::Interface::GetPowerStateMappingCompleterBase::ReplySuccess(::fidl::Array<SystemPowerStateInfo, 6> mapping) {
+void Controller::Interface::GetPowerStateMappingCompleterBase::ReplySuccess(::fidl::Array<SystemPowerStateInfo, 7> mapping) {
Controller_GetPowerStateMapping_Response response;
response.mapping = std::move(mapping);
@@ -2251,7 +2251,7 @@
_buffer.set_actual(sizeof(GetPowerStateMappingResponse));
CompleterBase::SendReply(::fidl::DecodedMessage<GetPowerStateMappingResponse>(std::move(_buffer)));
}
-void Controller::Interface::GetPowerStateMappingCompleterBase::ReplySuccess(::fidl::BytePart _buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping) {
+void Controller::Interface::GetPowerStateMappingCompleterBase::ReplySuccess(::fidl::BytePart _buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping) {
Controller_GetPowerStateMapping_Response response;
response.mapping = std::move(mapping);
diff --git a/zircon/system/fidl/fuchsia-device/gen/llcpp/include/fuchsia/device/llcpp/fidl.h b/zircon/system/fidl/fuchsia-device/gen/llcpp/include/fuchsia/device/llcpp/fidl.h
index cecbf18..b353b97 100644
--- a/zircon/system/fidl/fuchsia-device/gen/llcpp/include/fuchsia/device/llcpp/fidl.h
+++ b/zircon/system/fidl/fuchsia-device/gen/llcpp/include/fuchsia/device/llcpp/fidl.h
@@ -365,11 +365,11 @@
struct Controller_GetPowerStateMapping_Response {
static constexpr const fidl_type_t* Type = &fuchsia_device_Controller_GetPowerStateMapping_ResponseTable;
static constexpr uint32_t MaxNumHandles = 0;
- static constexpr uint32_t PrimarySize = 48;
+ static constexpr uint32_t PrimarySize = 56;
[[maybe_unused]]
static constexpr uint32_t MaxOutOfLine = 0;
- ::fidl::Array<SystemPowerStateInfo, 6> mapping = {};
+ ::fidl::Array<SystemPowerStateInfo, 7> mapping = {};
};
extern "C" const fidl_type_t fuchsia_device_Controller_GetPowerStateMapping_ResultTable;
@@ -452,7 +452,7 @@
static constexpr const fidl_type_t* Type = &fuchsia_device_Controller_GetPowerStateMapping_ResultTable;
static constexpr uint32_t MaxNumHandles = 0;
- static constexpr uint32_t PrimarySize = 52;
+ static constexpr uint32_t PrimarySize = 60;
[[maybe_unused]]
static constexpr uint32_t MaxOutOfLine = 0;
@@ -1104,11 +1104,11 @@
struct UpdatePowerStateMappingRequest final {
FIDL_ALIGNDECL
fidl_message_header_t _hdr;
- ::fidl::Array<SystemPowerStateInfo, 6> mapping;
+ ::fidl::Array<SystemPowerStateInfo, 7> mapping;
static constexpr const fidl_type_t* Type = &fuchsia_device_ControllerUpdatePowerStateMappingRequestTable;
static constexpr uint32_t MaxNumHandles = 0;
- static constexpr uint32_t PrimarySize = 64;
+ static constexpr uint32_t PrimarySize = 72;
static constexpr uint32_t MaxOutOfLine = 0;
static constexpr bool HasFlexibleEnvelope = false;
static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
@@ -1123,7 +1123,7 @@
static constexpr const fidl_type_t* Type = &fuchsia_device_ControllerGetPowerStateMappingResponseTable;
static constexpr uint32_t MaxNumHandles = 0;
- static constexpr uint32_t PrimarySize = 72;
+ static constexpr uint32_t PrimarySize = 80;
static constexpr uint32_t MaxOutOfLine = 0;
static constexpr bool HasFlexibleEnvelope = false;
static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
@@ -1389,7 +1389,7 @@
class UpdatePowerStateMapping_Impl final : private ::fidl::internal::OwnedSyncCallBase<ResponseType> {
using Super = ::fidl::internal::OwnedSyncCallBase<ResponseType>;
public:
- UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 6> mapping);
+ UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 7> mapping);
~UpdatePowerStateMapping_Impl() = default;
UpdatePowerStateMapping_Impl(UpdatePowerStateMapping_Impl&& other) = default;
UpdatePowerStateMapping_Impl& operator=(UpdatePowerStateMapping_Impl&& other) = default;
@@ -1670,7 +1670,7 @@
class UpdatePowerStateMapping_Impl final : private ::fidl::internal::UnownedSyncCallBase<ResponseType> {
using Super = ::fidl::internal::UnownedSyncCallBase<ResponseType>;
public:
- UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping, ::fidl::BytePart _response_buffer);
+ UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer);
~UpdatePowerStateMapping_Impl() = default;
UpdatePowerStateMapping_Impl(UpdatePowerStateMapping_Impl&& other) = default;
UpdatePowerStateMapping_Impl& operator=(UpdatePowerStateMapping_Impl&& other) = default;
@@ -1873,17 +1873,17 @@
// Updates the mapping between system power states to device power states. Used by the system
// wide power manager to manage power for this device
- // Allocates 88 bytes of message buffer on the stack. No heap allocation necessary.
- ResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 6> mapping);
+ // Allocates 96 bytes of message buffer on the stack. No heap allocation necessary.
+ ResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 7> mapping);
// Updates the mapping between system power states to device power states. Used by the system
// wide power manager to manage power for this device
// Caller provides the backing storage for FIDL message via request and response buffers.
- UnownedResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping, ::fidl::BytePart _response_buffer);
+ UnownedResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer);
// Get the mapping between system power states to device power states. Used by the system
// wide power manager to manage power for this device.
- // Allocates 88 bytes of message buffer on the stack. No heap allocation necessary.
+ // Allocates 96 bytes of message buffer on the stack. No heap allocation necessary.
ResultOf::GetPowerStateMapping GetPowerStateMapping();
// Get the mapping between system power states to device power states. Used by the system
@@ -2030,17 +2030,17 @@
// Updates the mapping between system power states to device power states. Used by the system
// wide power manager to manage power for this device
- // Allocates 88 bytes of message buffer on the stack. No heap allocation necessary.
- static ResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 6> mapping);
+ // Allocates 96 bytes of message buffer on the stack. No heap allocation necessary.
+ static ResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 7> mapping);
// Updates the mapping between system power states to device power states. Used by the system
// wide power manager to manage power for this device
// Caller provides the backing storage for FIDL message via request and response buffers.
- static UnownedResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping, ::fidl::BytePart _response_buffer);
+ static UnownedResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer);
// Get the mapping between system power states to device power states. Used by the system
// wide power manager to manage power for this device.
- // Allocates 88 bytes of message buffer on the stack. No heap allocation necessary.
+ // Allocates 96 bytes of message buffer on the stack. No heap allocation necessary.
static ResultOf::GetPowerStateMapping GetPowerStateMapping(zx::unowned_channel _client_end);
// Get the mapping between system power states to device power states. Used by the system
@@ -2328,15 +2328,15 @@
using UpdatePowerStateMappingCompleter = ::fidl::Completer<UpdatePowerStateMappingCompleterBase>;
- virtual void UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 6> mapping, UpdatePowerStateMappingCompleter::Sync _completer) = 0;
+ virtual void UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 7> mapping, UpdatePowerStateMappingCompleter::Sync _completer) = 0;
class GetPowerStateMappingCompleterBase : public _Base {
public:
void Reply(Controller_GetPowerStateMapping_Result result);
- void ReplySuccess(::fidl::Array<SystemPowerStateInfo, 6> mapping);
+ void ReplySuccess(::fidl::Array<SystemPowerStateInfo, 7> mapping);
void ReplyError(int32_t error);
void Reply(::fidl::BytePart _buffer, Controller_GetPowerStateMapping_Result result);
- void ReplySuccess(::fidl::BytePart _buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping);
+ void ReplySuccess(::fidl::BytePart _buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping);
void Reply(::fidl::DecodedMessage<GetPowerStateMappingResponse> params);
protected: