aboutsummaryrefslogtreecommitdiff
path: root/kapi
diff options
context:
space:
mode:
Diffstat (limited to 'kapi')
-rw-r--r--kapi/include/kapi/devices/bus.hpp61
1 files changed, 57 insertions, 4 deletions
diff --git a/kapi/include/kapi/devices/bus.hpp b/kapi/include/kapi/devices/bus.hpp
index a8d7df8..ccaf0f2 100644
--- a/kapi/include/kapi/devices/bus.hpp
+++ b/kapi/include/kapi/devices/bus.hpp
@@ -2,12 +2,17 @@
#define TEACHOS_KAPI_DEVICES_BUS_HPP
#include "kapi/devices/device.hpp"
+#include "kapi/system.hpp"
#include <kstd/memory>
+#include <kstd/print>
#include <kstd/string>
#include <kstd/vector>
+#include <algorithm>
+#include <atomic>
#include <cstddef>
+#include <utility>
namespace kapi::devices
{
@@ -23,17 +28,65 @@ namespace kapi::devices
: device(major, minor, name)
{}
+ //! Initialize the bus and all of its children.
+ //!
+ //! @return true iff. the bus and all of its children are healthy, false otherwise.
+ auto init() -> bool final
+ {
+ if (m_initialized.test_and_set())
+ {
+ return true;
+ }
+
+ if (!probe())
+ {
+ return false;
+ }
+
+ return std::ranges::fold_left(m_devices, true, [&](bool acc, auto & child) -> bool {
+ kstd::println("[kAPI:BUS] Initializing child device {}@{}", child->name(), name());
+ return acc && child->init();
+ });
+ }
+
//! Attach a child device to this bus.
//!
//! Whenever a device is attached to a bus, the bus takes sole ownership of the device.
//!
//! @param child The child device to attach.
- virtual auto add_child(kstd::unique_ptr<device> child) -> void = 0;
+ auto add_child(kstd::unique_ptr<device> child) -> void
+ {
+ auto observer = m_observers.emplace_back(child.get());
+ m_devices.push_back(std::move(child));
- //! Get a list of all child devices attached to this bus.
+ if (m_initialized.test())
+ {
+ kstd::println("[kAPI:BUS] Initializing child device {}@{}", observer->name(), name());
+ if (!observer->init())
+ {
+ kapi::system::panic("[kAPI:BUS] Failed to initialize child device");
+ }
+ }
+ }
+
+ [[nodiscard]] auto children() const -> kstd::vector<kstd::observer_ptr<device>> const &
+ {
+ return m_observers;
+ }
+
+ protected:
+ //! Probe the bus hardware state.
//!
- //! @return A reference to list of child devices of this bus.
- [[nodiscard]] virtual auto children() const -> kstd::vector<kstd::observer_ptr<device>> const & = 0;
+ //! @return true iff. the bus hardware is healthy, false otherwise.
+ auto virtual probe() -> bool
+ {
+ return true;
+ }
+
+ private:
+ kstd::vector<kstd::unique_ptr<device>> m_devices;
+ kstd::vector<kstd::observer_ptr<device>> m_observers;
+ std::atomic_flag m_initialized{};
};
} // namespace kapi::devices