Kernel: DevFS now stores all devices

This allows removing hack in PCI that was required to keep NVMe
controller alive.
This commit is contained in:
Bananymous 2024-01-24 14:33:50 +02:00
parent 5001fa58e0
commit 2cee2a85e6
3 changed files with 17 additions and 39 deletions

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <BAN/Vector.h>
#include <kernel/Device/Device.h> #include <kernel/Device/Device.h>
#include <kernel/FS/TmpFS/FileSystem.h> #include <kernel/FS/TmpFS/FileSystem.h>
#include <kernel/Semaphore.h> #include <kernel/Semaphore.h>
@ -17,7 +18,6 @@ namespace Kernel
void add_device(BAN::RefPtr<Device>); void add_device(BAN::RefPtr<Device>);
void add_inode(BAN::StringView path, BAN::RefPtr<TmpInode>); void add_inode(BAN::StringView path, BAN::RefPtr<TmpInode>);
void for_each_device(const BAN::Function<BAN::Iteration(Device*)>& callback);
dev_t get_next_dev() const; dev_t get_next_dev() const;
int get_next_input_device() const; int get_next_input_device() const;
@ -32,6 +32,8 @@ namespace Kernel
private: private:
mutable SpinLock m_device_lock; mutable SpinLock m_device_lock;
BAN::Vector<BAN::RefPtr<Device>> m_devices;
Semaphore m_sync_done; Semaphore m_sync_done;
Semaphore m_sync_semaphore; Semaphore m_sync_semaphore;
volatile bool m_should_sync { false }; volatile bool m_should_sync { false };

View File

@ -39,17 +39,12 @@ namespace Kernel
{ {
while (true) while (true)
{ {
s_instance->m_device_lock.lock(); {
s_instance->for_each_inode( LockGuard _(s_instance->m_device_lock);
[](BAN::RefPtr<TmpInode> inode) for (auto& device : s_instance->m_devices)
{ device->update();
if (inode->is_device()) }
static_cast<Device*>(inode.ptr())->update(); SystemTimer::get().sleep(10);
return BAN::Iteration::Continue;
}
);
s_instance->m_device_lock.unlock();
Scheduler::get().reschedule();
} }
}, nullptr }, nullptr
); );
@ -72,16 +67,11 @@ namespace Kernel
s_instance->m_device_lock.lock(); s_instance->m_device_lock.lock();
} }
s_instance->for_each_inode( for (auto& device : s_instance->m_devices)
[](BAN::RefPtr<TmpInode> inode) if (device->is_storage_device())
{ if (auto ret = static_cast<StorageDevice*>(device.ptr())->sync_disk_cache(); ret.is_error())
if (inode->is_device()) dwarnln("disk sync: {}", ret.error());
if (((Device*)inode.ptr())->is_storage_device())
if (auto ret = static_cast<StorageDevice*>(inode.ptr())->sync_disk_cache(); ret.is_error())
dwarnln("disk sync: {}", ret.error());
return BAN::Iteration::Continue;
}
);
s_instance->m_should_sync = false; s_instance->m_should_sync = false;
s_instance->m_sync_done.unblock(); s_instance->m_sync_done.unblock();
} }
@ -118,29 +108,19 @@ namespace Kernel
void DevFileSystem::add_device(BAN::RefPtr<Device> device) void DevFileSystem::add_device(BAN::RefPtr<Device> device)
{ {
LockGuard _(m_device_lock);
ASSERT(!device->name().contains('/')); ASSERT(!device->name().contains('/'));
MUST(static_cast<TmpDirectoryInode*>(root_inode().ptr())->link_inode(*device, device->name())); MUST(static_cast<TmpDirectoryInode*>(root_inode().ptr())->link_inode(*device, device->name()));
MUST(m_devices.push_back(device));
} }
void DevFileSystem::add_inode(BAN::StringView path, BAN::RefPtr<TmpInode> inode) void DevFileSystem::add_inode(BAN::StringView path, BAN::RefPtr<TmpInode> inode)
{ {
ASSERT(!inode->is_device());
ASSERT(!path.contains('/')); ASSERT(!path.contains('/'));
MUST(static_cast<TmpDirectoryInode*>(root_inode().ptr())->link_inode(*inode, path)); MUST(static_cast<TmpDirectoryInode*>(root_inode().ptr())->link_inode(*inode, path));
} }
void DevFileSystem::for_each_device(const BAN::Function<BAN::Iteration(Device*)>& callback)
{
LockGuard _(m_device_lock);
for_each_inode(
[&](BAN::RefPtr<Kernel::TmpInode> inode)
{
if (!inode->is_device())
return BAN::Iteration::Continue;
return callback(static_cast<Device*>(inode.ptr()));
}
);
}
dev_t DevFileSystem::get_next_dev() const dev_t DevFileSystem::get_next_dev() const
{ {
LockGuard _(m_device_lock); LockGuard _(m_device_lock);

View File

@ -172,12 +172,8 @@ namespace Kernel::PCI
dprintln("ATA: {}", res.error()); dprintln("ATA: {}", res.error());
break; break;
case 0x08: case 0x08:
// FIXME: HACK if inode initialization fails before it attaches to DevFS,
// it will kernel panic. This is used to make nvme eternal
if (auto res = NVMeController::create(pci_device); res.is_error()) if (auto res = NVMeController::create(pci_device); res.is_error())
dprintln("NVMe: {}", res.error()); dprintln("NVMe: {}", res.error());
else
res.value()->ref();
break; break;
default: default:
dprintln("unsupported storage device (pci {2H}.{2H}.{2H})", pci_device.class_code(), pci_device.subclass(), pci_device.prog_if()); dprintln("unsupported storage device (pci {2H}.{2H}.{2H})", pci_device.class_code(), pci_device.subclass(), pci_device.prog_if());