| // Copyright 2022 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 SRC_ACPI_MULTIPLY_ACPI_MULTIPLY_H_ |
| #define SRC_ACPI_MULTIPLY_ACPI_MULTIPLY_H_ |
| |
| #include <fidl/fuchsia.driver.framework/cpp/markers.h> |
| #include <fidl/fuchsia.driver.framework/cpp/wire_types.h> |
| #include <fidl/fuchsia.hardware.acpi/cpp/markers.h> |
| #include <fidl/sample.acpi.multiply/cpp/wire.h> |
| #include <lib/async/cpp/irq.h> |
| #include <lib/driver2/logger.h> |
| #include <lib/driver2/namespace.h> |
| #include <lib/fdf/cpp/dispatcher.h> |
| #include <lib/mmio/mmio-buffer.h> |
| #include <lib/sys/component/llcpp/outgoing_directory.h> |
| #include <lib/zx/interrupt.h> |
| |
| #include <list> |
| |
| namespace acpi_multiply { |
| |
| class AcpiMultiplyDriver : public fidl::WireServer<sample_acpi_multiply::Device> { |
| public: |
| AcpiMultiplyDriver(async_dispatcher_t* dispatcher, |
| fidl::WireSharedClient<fuchsia_driver_framework::Node> node, |
| driver::Namespace ns, driver::Logger logger) |
| : dispatcher_(dispatcher), |
| node_(std::move(node)), |
| outgoing_(component::OutgoingDirectory::Create(dispatcher)), |
| ns_(std::move(ns)), |
| logger_(std::move(logger)) {} |
| |
| virtual ~AcpiMultiplyDriver() = default; |
| |
| static constexpr const char* Name() { return "acpi-multiply"; } |
| |
| static zx::status<std::unique_ptr<AcpiMultiplyDriver>> Start( |
| fuchsia_driver_framework::wire::DriverStartArgs& start_args, |
| fdf::UnownedDispatcher dispatcher, |
| fidl::WireSharedClient<fuchsia_driver_framework::Node> node, driver::Namespace ns, |
| driver::Logger logger); |
| |
| void Multiply(MultiplyRequestView request, MultiplyCompleter::Sync& completer); |
| |
| private: |
| struct Operation { |
| // Operands to the multiply. |
| uint32_t a; |
| uint32_t b; |
| // Completer. |
| MultiplyCompleter::Async completer; |
| }; |
| |
| zx::status<> Run(fidl::ServerEnd<fuchsia_io::Directory> outgoing_dir); |
| |
| void HandleIrq(async_dispatcher_t* dispatcher, async::IrqBase* irq, zx_status_t status, |
| const zx_packet_interrupt_t* interrupt); |
| |
| void DoMultiply(Operation operation) __TA_REQUIRES(completer_lock_); |
| |
| async_dispatcher_t* const dispatcher_; |
| std::optional<fdf::MmioBuffer> mmio_; |
| zx::interrupt irq_; |
| async::IrqMethod<AcpiMultiplyDriver, &AcpiMultiplyDriver::HandleIrq> irq_method_{this}; |
| fidl::WireSyncClient<fuchsia_hardware_acpi::Device> acpi_; |
| |
| // TODO(fxbug.dev/99975): This will no longer be necessary once interrupts can be handled without |
| // spawning a separate dispatcher thread. |
| std::mutex completer_lock_; |
| std::optional<MultiplyCompleter::Async> cur_completer_ __TA_GUARDED(completer_lock_); |
| std::list<Operation> operation_queue_ __TA_GUARDED(completer_lock_); |
| |
| fidl::WireSharedClient<fuchsia_driver_framework::Node> node_; |
| |
| component::OutgoingDirectory outgoing_; |
| driver::Namespace ns_; |
| driver::Logger logger_; |
| |
| // Used by the self-test. |
| fidl::WireClient<sample_acpi_multiply::Device> client_; |
| }; |
| |
| } // namespace acpi_multiply |
| |
| #endif /* SRC_ACPI_MULTIPLY_ACPI_MULTIPLY_H_ */ |