Luna/kernel/src/fs/devices/DeviceRegistry.cpp

78 lines
2.1 KiB
C++
Raw Normal View History

#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/NullDevice.h"
2023-03-30 21:19:16 +02:00
#include "fs/devices/ZeroDevice.h"
#include "fs/tmpfs/FileSystem.h"
#include "thread/Thread.h"
#include <luna/Vector.h>
struct DeviceDescriptor
{
SharedPtr<Device> device;
u32 major;
u32 minor;
const char* name;
mode_t mode;
};
Vector<DeviceDescriptor> g_available_devices = {};
SharedPtr<VFS::FileSystem> g_device_fs;
namespace DeviceRegistry
{
Result<SharedPtr<Device>> 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<void> create_special_device_inode(DeviceDescriptor& descriptor)
{
auto inode = TRY(g_device_fs->create_device_inode(descriptor.major, descriptor.minor));
inode->chmod(descriptor.mode);
TRY(g_device_fs->root_inode()->add_entry(inode, descriptor.name));
return {};
}
Result<void> register_special_device(u32 major, u32 minor, SharedPtr<Device> device, const char* name, mode_t mode)
{
for (const auto& descriptor : g_available_devices)
{
if (descriptor.major == major && descriptor.minor == minor) return err(EEXIST);
}
kdbgln("DeviceRegistry: registered new device type %u:%u at path /dev/%s", major, minor, name);
auto desc = DeviceDescriptor { .device = device, .major = major, .minor = minor, .name = name, .mode = mode };
TRY(g_available_devices.try_append(desc));
TRY(create_special_device_inode(desc));
return {};
}
Result<void> init()
{
auto device_fs = TRY(TmpFS::FileSystem::create());
TRY(VFS::mount("/dev", device_fs, Credentials {}));
g_device_fs = device_fs;
NullDevice::create();
ZeroDevice::create();
ConsoleDevice::create();
FramebufferDevice::create();
return {};
}
}