#include "fs/devices/DeviceRegistry.h" #include "Log.h" #include "fs/VFS.h" #include "fs/devices/ConsoleDevice.h" #include "fs/devices/FramebufferDevice.h" #include "fs/devices/FullDevice.h" #include "fs/devices/KeyboardDevice.h" #include "fs/devices/MouseDevice.h" #include "fs/devices/NullDevice.h" #include "fs/devices/UARTDevice.h" #include "fs/devices/ZeroDevice.h" #include "fs/tmpfs/FileSystem.h" #include "thread/Thread.h" #include struct DeviceDescriptor { SharedPtr device; u32 major; u32 minor; const char* name; mode_t mode; }; Vector g_available_devices = {}; namespace DeviceRegistry { Result> fetch_special_device(u32 major, u32 minor) { for (const auto& descriptor : g_available_devices) { if (descriptor.major == major && descriptor.minor == minor) return descriptor.device; } return err(ENODEV); } Result create_special_device_inode(SharedPtr fs, const DeviceDescriptor& descriptor) { auto inode = TRY(fs->create_device_inode(descriptor.major, descriptor.minor, descriptor.mode)); TRY(fs->root_inode()->add_entry(inode, descriptor.name)); return {}; } Result register_special_device(u32 major, u32 minor, SharedPtr device, mode_t mode) { for (const auto& descriptor : g_available_devices) { if (descriptor.major == major && descriptor.minor == minor) return err(EEXIST); } const char* name = device->device_path().chars(); #ifdef DEVICE_REGISTRY_DEBUG kdbgln("DeviceRegistry: registered new device type %u:%u at path /%s in devfs", major, minor, name); #endif auto desc = DeviceDescriptor { .device = device, .major = major, .minor = minor, .name = name, .mode = mode }; TRY(g_available_devices.try_append(desc)); return {}; } Result init() { NullDevice::create(); ZeroDevice::create(); FullDevice::create(); ConsoleDevice::create(); FramebufferDevice::create(); UARTDevice::create(); MouseDevice::create(); KeyboardDevice::create(); return {}; } dev_t next_null_device_id() { static u32 next_minor = 0; return luna_dev_makedev(0, next_minor++); } // FIXME: This devfs will only contain the devices registered before its creation. Otherwise, created devfs // instances would have to be stored using WeakPtr or something (which doesn't exist atm)... Result> create_devfs_instance() { auto fs = TRY(TmpFS::FileSystem::create()); for (const auto& descriptor : g_available_devices) TRY(create_special_device_inode(fs, descriptor)); return fs; } }