aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kapi/kapi/devices/interface_registry.hpp7
-rw-r--r--kernel/kapi/devices/interface_registry.cpp14
-rw-r--r--kernel/kernel/filesystem/device_inode.cpp24
3 files changed, 43 insertions, 2 deletions
diff --git a/kapi/kapi/devices/interface_registry.hpp b/kapi/kapi/devices/interface_registry.hpp
index ae8b5c1a..b1dfa08e 100644
--- a/kapi/kapi/devices/interface_registry.hpp
+++ b/kapi/kapi/devices/interface_registry.hpp
@@ -121,6 +121,13 @@ namespace kapi::devices
//! @return An entry representing the published interface if it exists, an error otherwise.
[[nodiscard]] auto find(interface interface, std::string_view name) const -> kstd::result<entry>;
+ //! Find an entry for a given interface on a specific device.
+ //!
+ //! @param interface The interface to look for.
+ //! @param device The device to look for.
+ //! @return An entry representing the published interface if it exists, an error otherwise.
+ [[nodiscard]] auto find(interface interface, device const & device) const -> kstd::result<entry>;
+
//! Find an entry for a given interface on a device with the given name.
//!
//! @tparam Interface The interface type to look for.
diff --git a/kernel/kapi/devices/interface_registry.cpp b/kernel/kapi/devices/interface_registry.cpp
index da3d080a..d959c857 100644
--- a/kernel/kapi/devices/interface_registry.cpp
+++ b/kernel/kapi/devices/interface_registry.cpp
@@ -97,6 +97,20 @@ namespace kapi::devices
return *found;
}
+ auto interface_registry::find(interface interface, device const & device) const -> kstd::result<entry>
+ {
+ auto found = std::ranges::find_if(m_entries, [&](auto e) {
+ auto locked_device = e.device();
+ return e.interface() == interface && locked_device && locked_device.get() == &device;
+ });
+ if (found == m_entries.cend())
+ {
+ return kstd::failure(make_error_code(kstd::errc::no_such_device));
+ }
+
+ return *found;
+ }
+
} // namespace kapi::devices
namespace kapi::test_support::devices
diff --git a/kernel/kernel/filesystem/device_inode.cpp b/kernel/kernel/filesystem/device_inode.cpp
index 33037a52..0ff8dce6 100644
--- a/kernel/kernel/filesystem/device_inode.cpp
+++ b/kernel/kernel/filesystem/device_inode.cpp
@@ -16,6 +16,26 @@
#include <optional>
+namespace
+{
+ template<typename Interface>
+ auto resolve(kapi::devices::device & device) -> Interface *
+ {
+ if (auto * direct = device.as<Interface>())
+ {
+ return direct;
+ }
+
+ auto found = kapi::devices::interface_registry::get().find(Interface::id, device);
+ if (!found)
+ {
+ return nullptr;
+ }
+
+ return found->template as<Interface>();
+ }
+} // namespace
+
namespace kernel::filesystem
{
device_inode::device_inode(kstd::shared_ptr<kapi::devices::device> const & device)
@@ -41,7 +61,7 @@ namespace kernel::filesystem
auto device_inode::read(void * buffer, kstd::units::bytes offset, kstd::units::bytes size) const
-> kstd::result<kstd::units::bytes>
{
- if (auto block_device = m_device->as<kapi::devices::block_device>())
+ if (auto block_device = resolve<kapi::devices::block_device>(*m_device))
{
return devices::block_device_utils::read(*block_device, buffer, offset, size);
}
@@ -52,7 +72,7 @@ namespace kernel::filesystem
auto device_inode::write(void const * buffer, kstd::units::bytes offset, kstd::units::bytes size)
-> kstd::result<kstd::units::bytes>
{
- if (auto block_device = m_device->as<kapi::devices::block_device>())
+ if (auto block_device = resolve<kapi::devices::block_device>(*m_device))
{
return devices::block_device_utils::write(*block_device, buffer, offset, size);
}