2023-03-18 09:10:33 +01:00
|
|
|
#include "fs/devices/DeviceRegistry.h"
|
|
|
|
#include "Log.h"
|
2023-05-17 19:40:37 +02:00
|
|
|
#include "fs/VFS.h"
|
2023-03-18 09:10:33 +01:00
|
|
|
#include "fs/devices/ConsoleDevice.h"
|
2023-04-21 18:18:15 +02:00
|
|
|
#include "fs/devices/FramebufferDevice.h"
|
2023-05-27 10:42:45 +02:00
|
|
|
#include "fs/devices/FullDevice.h"
|
2023-08-02 17:20:13 +02:00
|
|
|
#include "fs/devices/KeyboardDevice.h"
|
2023-08-02 11:55:45 +02:00
|
|
|
#include "fs/devices/MouseDevice.h"
|
2023-03-18 09:10:33 +01:00
|
|
|
#include "fs/devices/NullDevice.h"
|
2023-07-21 14:09:37 +02:00
|
|
|
#include "fs/devices/UARTDevice.h"
|
2023-03-30 21:19:16 +02:00
|
|
|
#include "fs/devices/ZeroDevice.h"
|
2023-05-17 19:40:37 +02:00
|
|
|
#include "fs/tmpfs/FileSystem.h"
|
|
|
|
#include "thread/Thread.h"
|
2023-03-18 09:10:33 +01:00
|
|
|
#include <luna/Vector.h>
|
|
|
|
|
|
|
|
struct DeviceDescriptor
|
|
|
|
{
|
2023-05-09 18:31:27 +02:00
|
|
|
SharedPtr<Device> device;
|
2023-03-18 09:10:33 +01:00
|
|
|
u32 major;
|
|
|
|
u32 minor;
|
2023-05-17 19:40:37 +02:00
|
|
|
const char* name;
|
|
|
|
mode_t mode;
|
2023-03-18 09:10:33 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
Vector<DeviceDescriptor> g_available_devices = {};
|
|
|
|
|
|
|
|
namespace DeviceRegistry
|
|
|
|
{
|
2023-05-09 18:31:27 +02:00
|
|
|
Result<SharedPtr<Device>> fetch_special_device(u32 major, u32 minor)
|
2023-03-18 09:10:33 +01:00
|
|
|
{
|
|
|
|
for (const auto& descriptor : g_available_devices)
|
|
|
|
{
|
2023-05-09 18:31:27 +02:00
|
|
|
if (descriptor.major == major && descriptor.minor == minor) return descriptor.device;
|
2023-03-18 09:10:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return err(ENODEV);
|
|
|
|
}
|
|
|
|
|
2023-06-02 21:45:31 +02:00
|
|
|
Result<void> create_special_device_inode(SharedPtr<VFS::FileSystem> fs, const DeviceDescriptor& descriptor)
|
2023-05-17 19:52:26 +02:00
|
|
|
{
|
2023-08-01 17:20:28 +02:00
|
|
|
auto inode = TRY(fs->create_device_inode(descriptor.major, descriptor.minor, descriptor.mode));
|
2023-06-02 21:45:31 +02:00
|
|
|
TRY(fs->root_inode()->add_entry(inode, descriptor.name));
|
2023-05-17 19:52:26 +02:00
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2023-06-16 21:46:51 +02:00
|
|
|
Result<void> register_special_device(u32 major, u32 minor, SharedPtr<Device> device, mode_t mode)
|
2023-03-18 09:10:33 +01:00
|
|
|
{
|
|
|
|
for (const auto& descriptor : g_available_devices)
|
|
|
|
{
|
|
|
|
if (descriptor.major == major && descriptor.minor == minor) return err(EEXIST);
|
|
|
|
}
|
|
|
|
|
2023-06-16 21:46:51 +02:00
|
|
|
const char* name = device->device_path().chars();
|
|
|
|
|
2023-06-18 20:18:00 +02:00
|
|
|
#ifdef DEVICE_REGISTRY_DEBUG
|
2023-06-02 21:45:31 +02:00
|
|
|
kdbgln("DeviceRegistry: registered new device type %u:%u at path /%s in devfs", major, minor, name);
|
2023-06-18 20:18:00 +02:00
|
|
|
#endif
|
2023-05-17 19:40:37 +02:00
|
|
|
|
|
|
|
auto desc = DeviceDescriptor { .device = device, .major = major, .minor = minor, .name = name, .mode = mode };
|
|
|
|
|
|
|
|
TRY(g_available_devices.try_append(desc));
|
2023-03-18 09:10:33 +01:00
|
|
|
|
2023-05-17 19:40:37 +02:00
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2023-03-18 09:10:33 +01:00
|
|
|
Result<void> init()
|
|
|
|
{
|
2023-05-09 18:31:27 +02:00
|
|
|
NullDevice::create();
|
|
|
|
ZeroDevice::create();
|
2023-05-27 10:42:45 +02:00
|
|
|
FullDevice::create();
|
2023-05-09 18:31:27 +02:00
|
|
|
ConsoleDevice::create();
|
|
|
|
FramebufferDevice::create();
|
2023-07-21 14:09:37 +02:00
|
|
|
UARTDevice::create();
|
2023-08-02 11:55:45 +02:00
|
|
|
MouseDevice::create();
|
2023-08-02 17:20:13 +02:00
|
|
|
KeyboardDevice::create();
|
2023-03-18 09:10:33 +01:00
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
2023-05-23 20:45:24 +02:00
|
|
|
|
|
|
|
dev_t next_null_device_id()
|
|
|
|
{
|
|
|
|
static u32 next_minor = 0;
|
|
|
|
return luna_dev_makedev(0, next_minor++);
|
|
|
|
}
|
2023-06-02 21:45:31 +02:00
|
|
|
|
|
|
|
// 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<SharedPtr<VFS::FileSystem>> 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;
|
|
|
|
}
|
2023-03-18 09:10:33 +01:00
|
|
|
}
|