aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kapi/kapi/devices/driver.hpp5
-rw-r--r--kernel/kapi/devices/driver.cpp5
-rw-r--r--kernel/kernel/filesystem/device_number_registry.cpp21
3 files changed, 30 insertions, 1 deletions
diff --git a/kapi/kapi/devices/driver.hpp b/kapi/kapi/devices/driver.hpp
index 348e2841..20f66536 100644
--- a/kapi/kapi/devices/driver.hpp
+++ b/kapi/kapi/devices/driver.hpp
@@ -80,6 +80,11 @@ namespace kapi::devices
//! Drivers that want to claim an auto-populated device node in devfs must override this function.
[[nodiscard]] virtual auto claimed_major() const -> std::optional<std::uint8_t>;
+ //! Get the minor number associated with the driver and a device, if any.
+ //!
+ //! @param device The device associated with the relevant device number registration.
+ [[nodiscard]] virtual auto claimed_minor(device & device) const -> std::optional<std::uint8_t>;
+
//! Get the name of this driver.
//!
//! @return The static name of this driver.
diff --git a/kernel/kapi/devices/driver.cpp b/kernel/kapi/devices/driver.cpp
index ee16b4c2..4f0ce0e4 100644
--- a/kernel/kapi/devices/driver.cpp
+++ b/kernel/kapi/devices/driver.cpp
@@ -12,6 +12,11 @@ namespace kapi::devices
return std::nullopt;
}
+ auto driver::claimed_minor(device &) const -> std::optional<std::uint8_t>
+ {
+ return std::nullopt;
+ }
+
auto driver::query_facet(kapi::capabilities::facet_id) -> void *
{
return nullptr;
diff --git a/kernel/kernel/filesystem/device_number_registry.cpp b/kernel/kernel/filesystem/device_number_registry.cpp
index cced66e0..42663dba 100644
--- a/kernel/kernel/filesystem/device_number_registry.cpp
+++ b/kernel/kernel/filesystem/device_number_registry.cpp
@@ -9,6 +9,7 @@
#include <kstd/memory.hpp>
#include <kstd/mutex.hpp>
+#include <kstd/print.hpp>
#include <kstd/result.hpp>
#include <kstd/vector.hpp>
@@ -202,7 +203,25 @@ namespace kernel::filesystem
{
auto guard = kstd::lock_guard{m_lock};
- auto minor = allocate_minor(binding->posix_type, *driver_major);
+ auto minor = std::uint8_t{};
+ auto driver_minor = driver->claimed_minor(*device);
+ if (driver_minor)
+ {
+ minor = *driver_minor;
+ auto filtered = std::views::filter(
+ m_entries, [&](auto e) { return e.type == binding->posix_type && e.number.major == *driver_major; });
+ auto found = std::ranges::find_if(filtered, [&](auto e) { return e.minor == minor; }, &entry::number);
+ if (found != std::ranges::cend(filtered))
+ {
+ kstd::println(kstd::print_sink::stderr, "[OS:DEV] Driver '{}' tried to claim duplicate minor {}",
+ driver->name(), minor);
+ return;
+ }
+ }
+ else
+ {
+ minor = allocate_minor(binding->posix_type, *driver_major);
+ }
numbered = entry{
.number = {.major = *driver_major, .minor = minor},