aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/kapi/devices/device.cpp15
-rw-r--r--kernel/kapi/devices/interface_registry.cpp23
-rw-r--r--kernel/kapi/devices/interface_registry.tests.cpp10
-rw-r--r--kernel/kernel/filesystem/device_inode.cpp24
4 files changed, 39 insertions, 33 deletions
diff --git a/kernel/kapi/devices/device.cpp b/kernel/kapi/devices/device.cpp
index 4c63f6a4..3eb9aaac 100644
--- a/kernel/kapi/devices/device.cpp
+++ b/kernel/kapi/devices/device.cpp
@@ -12,6 +12,21 @@ namespace kapi::devices
: m_name(name)
{}
+ auto device::as(interface interface) noexcept -> void *
+ {
+ return query_interface(interface);
+ }
+
+ auto device::as(interface interface) const noexcept -> void const *
+ {
+ return const_cast<device *>(this)->query_interface(interface);
+ }
+
+ auto device::is_a(interface interface) const noexcept -> bool
+ {
+ return const_cast<device *>(this)->query_interface(interface) != nullptr;
+ }
+
auto device::name() const -> kstd::string const &
{
return m_name;
diff --git a/kernel/kapi/devices/interface_registry.cpp b/kernel/kapi/devices/interface_registry.cpp
index d959c857..2ff42aa3 100644
--- a/kernel/kapi/devices/interface_registry.cpp
+++ b/kernel/kapi/devices/interface_registry.cpp
@@ -85,30 +85,41 @@ namespace kapi::devices
return filtered;
}
- auto interface_registry::find(interface interface, std::string_view name) const -> kstd::result<entry>
+ auto interface_registry::resolve(interface interface, std::string_view name) -> void *
{
auto found = std::ranges::find_if(
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));
+ return nullptr;
+ }
+ else if (auto device = found->device())
+ {
+ return resolve(interface, *device);
}
- return *found;
+ return nullptr;
}
- auto interface_registry::find(interface interface, device const & device) const -> kstd::result<entry>
+ auto interface_registry::resolve(interface interface, device & device) -> void *
{
+ if (auto by_device = device.as(interface))
+ {
+ return by_device;
+ }
+
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 nullptr;
}
- return *found;
+ return found->implementation();
}
} // namespace kapi::devices
diff --git a/kernel/kapi/devices/interface_registry.tests.cpp b/kernel/kapi/devices/interface_registry.tests.cpp
index 100954ea..f82e867e 100644
--- a/kernel/kapi/devices/interface_registry.tests.cpp
+++ b/kernel/kapi/devices/interface_registry.tests.cpp
@@ -133,23 +133,23 @@ SCENARIO("Publishing and finding a device", "[kapi][devices][interface_registry]
THEN("find finds the published capability by name")
{
- REQUIRE(registry.find<probe_device>("probe0"));
+ REQUIRE(registry.resolve<probe_device>("probe0"));
}
THEN("find for an unpublished capability does not find a device")
{
- REQUIRE_FALSE(registry.find<const_device>("probe0"));
+ REQUIRE_FALSE(registry.resolve<const_device>("probe0"));
}
THEN("find for an unpublished device does not find a device")
{
- REQUIRE_FALSE(registry.find<probe_device>("probe1"));
+ REQUIRE_FALSE(registry.resolve<probe_device>("probe1"));
}
THEN("withdrawing an interface for a device removes it from the registry")
{
registry.unpublish(*device, probe_device::id);
- REQUIRE_FALSE(registry.find<probe_device>("probe0"));
+ REQUIRE_FALSE(registry.resolve<probe_device>("probe0"));
}
}
@@ -165,7 +165,7 @@ SCENARIO("Publishing and finding a device", "[kapi][devices][interface_registry]
THEN("find() no longer finds it")
{
- REQUIRE_FALSE(registry.find<probe_device>("probe0"));
+ REQUIRE_FALSE(registry.resolve<probe_device>("probe0"));
}
}
}
diff --git a/kernel/kernel/filesystem/device_inode.cpp b/kernel/kernel/filesystem/device_inode.cpp
index 0ff8dce6..b898c5eb 100644
--- a/kernel/kernel/filesystem/device_inode.cpp
+++ b/kernel/kernel/filesystem/device_inode.cpp
@@ -16,26 +16,6 @@
#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)
@@ -61,7 +41,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 = resolve<kapi::devices::block_device>(*m_device))
+ if (auto block_device = kapi::devices::interface_registry::get().resolve<kapi::devices::block_device>(*m_device))
{
return devices::block_device_utils::read(*block_device, buffer, offset, size);
}
@@ -72,7 +52,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 = resolve<kapi::devices::block_device>(*m_device))
+ if (auto block_device = kapi::devices::interface_registry::get().resolve<kapi::devices::block_device>(*m_device))
{
return devices::block_device_utils::write(*block_device, buffer, offset, size);
}