diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/kapi/devices/device.cpp | 5 | ||||
| -rw-r--r-- | kernel/kapi/devices/interface_registry.cpp | 10 | ||||
| -rw-r--r-- | kernel/kapi/devices/interface_registry.tests.cpp | 4 | ||||
| -rw-r--r-- | kernel/kernel/devices/storage.cpp | 2 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/device_number_registry.cpp | 61 | ||||
| -rw-r--r-- | kernel/kernel/filesystem/file_type_bindings.hpp | 10 |
6 files changed, 70 insertions, 22 deletions
diff --git a/kernel/kapi/devices/device.cpp b/kernel/kapi/devices/device.cpp index cbbd5405..4c63f6a4 100644 --- a/kernel/kapi/devices/device.cpp +++ b/kernel/kapi/devices/device.cpp @@ -32,6 +32,11 @@ namespace kapi::devices m_state = state; } + auto device::bound_driver() const noexcept -> driver * + { + return m_driver.lock().get(); + } + auto device::bind_driver(kstd::weak_ptr<struct driver> driver) -> void { m_driver = driver; diff --git a/kernel/kapi/devices/interface_registry.cpp b/kernel/kapi/devices/interface_registry.cpp index 8882e8db..da3d080a 100644 --- a/kernel/kapi/devices/interface_registry.cpp +++ b/kernel/kapi/devices/interface_registry.cpp @@ -46,7 +46,7 @@ namespace kapi::devices auto interface_registry::do_publish(kstd::shared_ptr<device> device, kstd::string name, interface interface, void * implementation) -> kstd::result<void> { - erase_if(m_entries, [interface](auto e) { return e.interface() == interface && e.device().expired(); }); + erase_if(m_entries, [interface](auto e) { return e.interface() == interface && !e.device(); }); if (!device || !implementation || name.empty()) { @@ -54,7 +54,7 @@ namespace kapi::devices } auto published = std::ranges::any_of(m_entries, [&](auto const & entry) { - return entry.interface() == interface && entry.device().lock().get() == device.get(); + return entry.interface() == interface && entry.device().get() == device.get(); }); if (published) @@ -70,7 +70,7 @@ namespace kapi::devices auto interface_registry::unpublish(device const & device, interface interface) -> void { erase_if(m_entries, [&](auto e) { - auto locked_device = e.device().lock(); + auto locked_device = e.device(); return e.interface() == interface && locked_device && locked_device.get() == &device; }); } @@ -79,7 +79,7 @@ namespace kapi::devices { auto filtered = m_entries; erase_if(filtered, [&](auto e) { - auto locked_device = e.device().lock(); + auto locked_device = e.device(); return !(e.interface() == interface && locked_device); }); return filtered; @@ -88,7 +88,7 @@ namespace kapi::devices auto interface_registry::find(interface interface, std::string_view name) const -> kstd::result<entry> { auto found = std::ranges::find_if( - m_entries, [&](auto e) { return e.interface() == interface && e.name() == name && e.device().lock(); }); + m_entries, [&](auto e) { return e.interface() == interface && e.name() == name && e.device(); }); if (found == m_entries.cend()) { return kstd::failure(make_error_code(kstd::errc::no_such_device)); diff --git a/kernel/kapi/devices/interface_registry.tests.cpp b/kernel/kapi/devices/interface_registry.tests.cpp index 78cd7ecf..100954ea 100644 --- a/kernel/kapi/devices/interface_registry.tests.cpp +++ b/kernel/kapi/devices/interface_registry.tests.cpp @@ -114,9 +114,9 @@ SCENARIO("Publishing and finding a device", "[kapi][devices][interface_registry] REQUIRE(probeable_devices[0].name() == "probe0"); } - THEN("the returned device pointer is lockable") + THEN("the returned device pointer is valid") { - REQUIRE(probeable_devices[0].device().lock()); + REQUIRE(probeable_devices[0].device()); } THEN("the returned implementation equals the result of device::as") diff --git a/kernel/kernel/devices/storage.cpp b/kernel/kernel/devices/storage.cpp index d5508270..cfdf3ec2 100644 --- a/kernel/kernel/devices/storage.cpp +++ b/kernel/kernel/devices/storage.cpp @@ -29,6 +29,6 @@ namespace kernel::devices::storage return nullptr; } - return block_devices.front().device().lock(); + return block_devices.front().device(); } } // namespace kernel::devices::storage
\ No newline at end of file diff --git a/kernel/kernel/filesystem/device_number_registry.cpp b/kernel/kernel/filesystem/device_number_registry.cpp index 430da00a..058ae322 100644 --- a/kernel/kernel/filesystem/device_number_registry.cpp +++ b/kernel/kernel/filesystem/device_number_registry.cpp @@ -12,13 +12,21 @@ #include <kstd/vector.hpp> #include <algorithm> +#include <cstdint> #include <optional> #include <ranges> namespace { constinit auto static instance = std::optional<kernel::filesystem::device_number_registry>{}; -} + + struct driver_group + { + kapi::devices::driver const * bound_driver; + std::uint8_t major; + kstd::vector<kapi::devices::interface_registry::entry> published; + }; +} // namespace namespace kernel::filesystem { @@ -88,17 +96,54 @@ namespace kernel::filesystem for (auto const & binding : file_type_bindings) { - auto next_minor = decltype(kapi::filesystem::device_number::minor){}; + auto groups = kstd::vector<driver_group>{}; for (auto const & published : m_interface_registry->all(binding.interface)) { - if (auto device = published.device().lock()) + auto device = published.device(); + if (!device) + { + continue; + } + + auto bound_driver = device->bound_driver(); + if (!bound_driver) + { + continue; + } + + auto claimed = bound_driver->claimed_major(); + if (!claimed) + { + continue; + } + + auto found_group = + std::ranges::find_if(groups, [&](auto const & group) { return group.bound_driver == bound_driver; }); + + if (found_group == groups.end()) + { + groups.push_back({.bound_driver = bound_driver, .major = *claimed, .published = {}}); + found_group = groups.end() - 1; + } + + found_group->published.push_back(published); + } + + for (auto const & group : groups) + { + auto next_minor = decltype(kapi::filesystem::device_number::minor){}; + + for (auto const & published : group.published) { - m_entries.emplace_back(kapi::filesystem::device_number{.major = binding.major, .minor = next_minor}, // - binding.posix_type, // - published.name(), // - published.device()); - ++next_minor; + if (auto device = published.device()) + { + m_entries.emplace_back(kapi::filesystem::device_number{.major = group.major, .minor = next_minor}, // + binding.posix_type, // + published.name(), // + published.device()); + ++next_minor; + } } } } diff --git a/kernel/kernel/filesystem/file_type_bindings.hpp b/kernel/kernel/filesystem/file_type_bindings.hpp index e33d5086..94f6a763 100644 --- a/kernel/kernel/filesystem/file_type_bindings.hpp +++ b/kernel/kernel/filesystem/file_type_bindings.hpp @@ -7,24 +7,22 @@ #include <kapi/devices.hpp> #include <array> -#include <cstdint> namespace kernel::filesystem { - //! A binding between an interface, a posix special file type, and a major number. + //! A binding between an interface, a posix special file type struct file_type_binding // NOLINT(cppcoreguidelines-pro-type-member-init) { kapi::devices::interface interface; file_type posix_type; - std::uint8_t major; }; - //! Predefined bindings for interface + file type + major number. + //! Predefined bindings for interface + file type //! - //! This array associates reserved major numbers with file types and interfaces. + //! This array associates published interfaces with files types. constexpr auto inline file_type_bindings = std::array{ - file_type_binding{kapi::devices::block_device::id, file_type::block, block_major_numbers::ram_disk}, + file_type_binding{kapi::devices::block_device::id, file_type::block}, }; } // namespace kernel::filesystem |
