#include #include #include #include #include #include #include #include #include #include #include namespace kapi::devices { bus::bus(kstd::string const & name) : device{name} {} auto bus::init() -> bool { if (m_init_was_called.test_and_set()) { kstd::println(kstd::print_sink::stderr, "[OS:DEV] Bus {} already initialized", name()); return true; } if (!enumerate()) { kstd::println(kstd::print_sink::stderr, "[OS:DEV] Bus {} enumeration failed", name()); return false; } auto child_status = std::ranges::fold_left(m_devices, true, [&](bool acc, auto & child) -> bool { kstd::println("[OS:DEV] Initializing child device {}@{}", child->name(), name()); return child->init() && acc; }); m_initialized.test_and_set(); return child_status; } auto bus::add_child(kstd::shared_ptr child) -> void { child->set_parent(kstd::static_pointer_cast(shared_from_this())); if (!kapi::devices::register_device(child)) { kapi::system::panic("[OS:DEV] Failed to register child device {}", child->name()); } auto & attached = m_devices.emplace_back(std::move(child)); attached->set_state(state::present); driver_registry::get().device_attached(attached); if (m_initialized.test()) { kstd::println("[OS:DEV] Initializing child device {}@{}", attached->name(), name()); if (!attached->init()) { kapi::system::panic("[OS:DEV] Failed to initialize child device"); } } } [[nodiscard]] auto bus::children() const -> std::span const> { return {m_devices.data(), m_devices.size()}; } auto bus::protocol() -> struct bus_protocol * { return nullptr; } auto bus::enumerate() -> bool { return true; } } // namespace kapi::devices