diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-07-26 11:37:52 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-07-26 11:37:52 +0200 |
| commit | 5a5fefba28a52feffadf2b810b2f935934aa7b0b (patch) | |
| tree | 4583579a3b964091455344969a3e9641fb8fef33 /kernel/kapi/devices/bus.cpp | |
| parent | ad43e9c9eac69b862789f2e132201cd5ceebaffa (diff) | |
| download | kernel-5a5fefba28a52feffadf2b810b2f935934aa7b0b.tar.xz kernel-5a5fefba28a52feffadf2b810b2f935934aa7b0b.zip | |
kapi/device: allow removing devices from busses
Diffstat (limited to 'kernel/kapi/devices/bus.cpp')
| -rw-r--r-- | kernel/kapi/devices/bus.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/kernel/kapi/devices/bus.cpp b/kernel/kapi/devices/bus.cpp index dad90a15..d917eb96 100644 --- a/kernel/kapi/devices/bus.cpp +++ b/kernel/kapi/devices/bus.cpp @@ -9,6 +9,7 @@ #include <kstd/string.hpp> #include <kstd/vector.hpp> +#include <algorithm> #include <span> #include <utility> @@ -23,6 +24,15 @@ namespace kapi::devices , m_protocol{&protocol} {} + bus::~bus() + { + auto children = m_devices; + for (auto const & child : children) + { + remove_child(*child); + } + } + auto bus::add_child(kstd::shared_ptr<device> child) -> void { child->set_parent(kstd::static_pointer_cast<bus>(shared_from_this())); @@ -32,12 +42,35 @@ namespace kapi::devices kapi::system::panic("[OS:DEV] Failed to register child device {}", child->name()); } + // TODO: lock bus + auto & attached = m_devices.emplace_back(std::move(child)); attached->set_state(state::present); + // TODO: unlock bus + driver_registry::get().device_attached(attached); } + auto bus::remove_child(device & device) -> bool // NOLINT(misc-no-recursion) + { + // TODO: lock bus + + auto found = std::ranges::find_if(m_devices, [&](auto const & d) { return d.get() == &device; }); + if (!found) + { + return false; + } + + auto lifeline = *found; + m_devices.erase(found); + + // TODO: unlock bus + + do_remove_child(*lifeline); + return true; + } + [[nodiscard]] auto bus::children() const -> std::span<kstd::shared_ptr<device> const> { return {m_devices.data(), m_devices.size()}; @@ -57,4 +90,37 @@ namespace kapi::devices return device::query_facet(facet); } + auto bus::do_remove_child(device & device) -> void // NOLINT(misc-no-recursion) + { + if (device.state() == state::removed) + { + return; + } + + if (auto child_bus = device.facet<bus>()) + { + auto grandchildren = kstd::vector<kstd::shared_ptr<kapi::devices::device>>{}; + // TODO: lock child bus + // NOTE: this could be more efficient one vector::assign is implemented. + grandchildren = kstd::vector(child_bus->m_devices.begin(), child_bus->m_devices.end()); + // TODO: unlock child bus + + for (auto & grandchild : grandchildren) + { + child_bus->remove_child(*grandchild); + } + } + + device.set_state(state::removed); + + if (auto bound_driver = device.bound_driver()) + { + bound_driver->unbind(device); + } + + facet_registry::get().withdraw_all_for(device); + device_registry::get().remove(device); + device.set_parent(kstd::weak_ptr<bus>{}); + } + } // namespace kapi::devices
\ No newline at end of file |
