Kernel: Move DeviceManager to its own file
This commit is contained in:
		
							parent
							
								
									b048630e5b
								
							
						
					
					
						commit
						a3ba6da6f3
					
				|  | @ -42,6 +42,7 @@ kernel/build_libc.o				\ | |||
| kernel/CPUID.o					\ | ||||
| kernel/Debug.o					\ | ||||
| kernel/Device.o					\ | ||||
| kernel/DeviceManager.o			\ | ||||
| kernel/Font.o					\ | ||||
| kernel/FS/Ext2.o				\ | ||||
| kernel/FS/VirtualFileSystem.o	\ | ||||
|  |  | |||
|  | @ -1,10 +1,7 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <BAN/StringView.h> | ||||
| #include <BAN/Vector.h> | ||||
| #include <kernel/FS/FileSystem.h> | ||||
| #include <kernel/FS/Inode.h> | ||||
| #include <kernel/SpinLock.h> | ||||
| 
 | ||||
| namespace Kernel | ||||
| { | ||||
|  | @ -47,53 +44,4 @@ namespace Kernel | |||
| 		virtual DeviceType device_type() const override { return DeviceType::CharacterDevice; } | ||||
| 	}; | ||||
| 
 | ||||
| 	class DeviceManager final : public FileSystem, public Inode | ||||
| 	{ | ||||
| 		BAN_NON_COPYABLE(DeviceManager); | ||||
| 		BAN_NON_MOVABLE(DeviceManager); | ||||
| 
 | ||||
| 	public: | ||||
| 		static void initialize(); | ||||
| 		static DeviceManager& get(); | ||||
| 
 | ||||
| 		void update(); | ||||
| 		void add_device(Device*); | ||||
| 
 | ||||
| 		virtual BAN::RefPtr<Inode> root_inode() override { return this; } | ||||
| 
 | ||||
| 		virtual InodeType inode_type() const override { return InodeType::Device; } | ||||
| 
 | ||||
| 		virtual BAN::StringView name() const override { return "device-manager"; } | ||||
| 
 | ||||
| 		virtual BAN::ErrorOr<BAN::RefPtr<Inode>> read_directory_inode(BAN::StringView) override; | ||||
| 		virtual BAN::ErrorOr<BAN::Vector<BAN::String>> read_directory_entries(size_t) override; | ||||
| 
 | ||||
| 	private: | ||||
| 		DeviceManager() = default; | ||||
| 
 | ||||
| 	private: | ||||
| 		SpinLock m_lock; | ||||
| 		BAN::Vector<Device*> m_devices; | ||||
| 
 | ||||
| 		friend class BAN::RefPtr<DeviceManager>; | ||||
| 
 | ||||
| 	public: | ||||
| 		virtual ino_t ino() const override { return 0; } | ||||
| 		virtual Mode mode() const override { return { Mode::IFDIR | Mode::IRUSR | Mode::IWUSR | Mode::IXUSR | Mode::IRGRP | Mode::IXGRP | Mode::IROTH | Mode::IXOTH }; } | ||||
| 		virtual nlink_t nlink() const override { return 0; } | ||||
| 		virtual uid_t uid() const override { return 0; } | ||||
| 		virtual gid_t gid() const override { return 0; } | ||||
| 		virtual off_t size() const override { return 0; } | ||||
| 		virtual timespec atime() const override { return { 0, 0 }; } | ||||
| 		virtual timespec mtime() const override { return { 0, 0 }; } | ||||
| 		virtual timespec ctime() const override { return { 0, 0 }; } | ||||
| 		virtual blksize_t blksize() const override { return 0; } | ||||
| 		virtual blkcnt_t blocks() const override { return 0; } | ||||
| 		virtual dev_t dev() const override { return 0x4900; } | ||||
| 		virtual dev_t rdev() const override { return 0x7854; } | ||||
| 
 | ||||
| 		virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t)        { ASSERT_NOT_REACHED(); } | ||||
| 		virtual BAN::ErrorOr<void> create_file(BAN::StringView, mode_t) { ASSERT_NOT_REACHED(); } | ||||
| 	}; | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,60 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <BAN/StringView.h> | ||||
| #include <kernel/FS/FileSystem.h> | ||||
| #include <kernel/Device.h> | ||||
| #include <kernel/SpinLock.h> | ||||
| 
 | ||||
| namespace Kernel | ||||
| { | ||||
| 
 | ||||
| 	class DeviceManager final : public FileSystem, public Inode | ||||
| 	{ | ||||
| 		BAN_NON_COPYABLE(DeviceManager); | ||||
| 		BAN_NON_MOVABLE(DeviceManager); | ||||
| 
 | ||||
| 	public: | ||||
| 		static void initialize(); | ||||
| 		static DeviceManager& get(); | ||||
| 
 | ||||
| 		void update(); | ||||
| 		void add_device(Device*); | ||||
| 
 | ||||
| 		virtual BAN::RefPtr<Inode> root_inode() override { return this; } | ||||
| 
 | ||||
| 		virtual InodeType inode_type() const override { return InodeType::Device; } | ||||
| 
 | ||||
| 		virtual BAN::StringView name() const override { return "device-manager"; } | ||||
| 
 | ||||
| 		virtual BAN::ErrorOr<BAN::RefPtr<Inode>> read_directory_inode(BAN::StringView) override; | ||||
| 		virtual BAN::ErrorOr<BAN::Vector<BAN::String>> read_directory_entries(size_t) override; | ||||
| 
 | ||||
| 	private: | ||||
| 		DeviceManager() = default; | ||||
| 
 | ||||
| 	private: | ||||
| 		SpinLock m_lock; | ||||
| 		BAN::Vector<Device*> m_devices; | ||||
| 
 | ||||
| 		friend class BAN::RefPtr<DeviceManager>; | ||||
| 
 | ||||
| 	public: | ||||
| 		virtual ino_t ino() const override { return 0; } | ||||
| 		virtual Mode mode() const override { return { Mode::IFDIR | Mode::IRUSR | Mode::IWUSR | Mode::IXUSR | Mode::IRGRP | Mode::IXGRP | Mode::IROTH | Mode::IXOTH }; } | ||||
| 		virtual nlink_t nlink() const override { return 1; } | ||||
| 		virtual uid_t uid() const override { return 0; } | ||||
| 		virtual gid_t gid() const override { return 0; } | ||||
| 		virtual off_t size() const override { return 0; } | ||||
| 		virtual timespec atime() const override { return { 0, 0 }; } | ||||
| 		virtual timespec mtime() const override { return { 0, 0 }; } | ||||
| 		virtual timespec ctime() const override { return { 0, 0 }; } | ||||
| 		virtual blksize_t blksize() const override { return 0; } | ||||
| 		virtual blkcnt_t blocks() const override { return 0; } | ||||
| 		virtual dev_t dev() const override { return 0x4900; } | ||||
| 		virtual dev_t rdev() const override { return 0x7854; } | ||||
| 
 | ||||
| 		virtual BAN::ErrorOr<size_t> read(size_t, void*, size_t)        { ASSERT_NOT_REACHED(); } | ||||
| 		virtual BAN::ErrorOr<void> create_file(BAN::StringView, mode_t) { ASSERT_NOT_REACHED(); } | ||||
| 	}; | ||||
| 
 | ||||
| } | ||||
|  | @ -2,6 +2,7 @@ | |||
| 
 | ||||
| #include <BAN/Memory.h> | ||||
| #include <BAN/String.h> | ||||
| #include <BAN/StringView.h> | ||||
| #include <BAN/Vector.h> | ||||
| 
 | ||||
| #include <sys/types.h> | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <kernel/DeviceManager.h> | ||||
| #include <kernel/PCI.h> | ||||
| #include <kernel/SpinLock.h> | ||||
| #include <kernel/Storage/StorageController.h> | ||||
| 
 | ||||
| namespace Kernel | ||||
|  |  | |||
|  | @ -1,115 +1,12 @@ | |||
| #include <BAN/Time.h> | ||||
| #include <kernel/Device.h> | ||||
| #include <kernel/LockGuard.h> | ||||
| #include <kernel/PCI.h> | ||||
| #include <kernel/Process.h> | ||||
| #include <kernel/RTC.h> | ||||
| #include <kernel/Storage/ATAController.h> | ||||
| 
 | ||||
| namespace Kernel | ||||
| { | ||||
| 
 | ||||
| 	static DeviceManager* s_instance = nullptr; | ||||
| 
 | ||||
| 	Device::Device() | ||||
| 		: m_create_time({ BAN::to_unix_time(RTC::get_current_time()), 0 }) | ||||
| 	{ } | ||||
| 
 | ||||
| 	void DeviceManager::initialize() | ||||
| 	{ | ||||
| 		ASSERT(s_instance == nullptr); | ||||
| 
 | ||||
| 		s_instance = new DeviceManager; | ||||
| 		ASSERT(s_instance != nullptr); | ||||
| 		 | ||||
| 		for (const auto& pci_device : PCI::get().devices()) | ||||
| 		{ | ||||
| 			switch (pci_device.class_code()) | ||||
| 			{ | ||||
| 				case 0x01: | ||||
| 				{ | ||||
| 					StorageController* controller = nullptr; | ||||
| 					switch (pci_device.subclass()) | ||||
| 					{ | ||||
| 						case 0x01: | ||||
| 							if (auto res = ATAController::create(pci_device); res.is_error()) | ||||
| 								dprintln("{}", res.error()); | ||||
| 							else | ||||
| 								controller = res.value(); | ||||
| 							break; | ||||
| 						default: | ||||
| 							dprintln("unsupported storage device (pci subclass {2H})", pci_device.subclass()); | ||||
| 							break; | ||||
| 					} | ||||
| 
 | ||||
| 					if (controller) | ||||
| 					{ | ||||
| 						s_instance->add_device(controller); | ||||
| 						for (auto* device : controller->devices()) | ||||
| 						{ | ||||
| 							s_instance->add_device(device); | ||||
| 							for (auto* partition : device->partitions()) | ||||
| 								s_instance->add_device(partition); | ||||
| 						} | ||||
| 					} | ||||
| 					break; | ||||
| 				} | ||||
| 				default: | ||||
| 					break; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		MUST(Process::create_kernel( | ||||
| 			[](void*) | ||||
| 			{ | ||||
| 				while (true) | ||||
| 				{ | ||||
| 					DeviceManager::get().update(); | ||||
| 					PIT::sleep(1); | ||||
| 				} | ||||
| 			}, nullptr) | ||||
| 		); | ||||
| 	} | ||||
| 
 | ||||
| 	DeviceManager& DeviceManager::get() | ||||
| 	{ | ||||
| 		ASSERT(s_instance); | ||||
| 		return *s_instance; | ||||
| 	} | ||||
| 
 | ||||
| 	void DeviceManager::update() | ||||
| 	{ | ||||
| 		LockGuard _(m_lock); | ||||
| 		for (Device* device : m_devices) | ||||
| 			device->update(); | ||||
| 	} | ||||
| 
 | ||||
| 	void DeviceManager::add_device(Device* device) | ||||
| 	{ | ||||
| 		LockGuard _(m_lock); | ||||
| 		MUST(m_devices.push_back(device)); | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::ErrorOr<BAN::RefPtr<Inode>> DeviceManager::read_directory_inode(BAN::StringView name) | ||||
| 	{ | ||||
| 		LockGuard _(m_lock); | ||||
| 		for (Device* device : m_devices) | ||||
| 			if (device->name() == name) | ||||
| 				return BAN::RefPtr<Inode>(device); | ||||
| 		return BAN::Error::from_errno(ENOENT); | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::ErrorOr<BAN::Vector<BAN::String>> DeviceManager::read_directory_entries(size_t index) | ||||
| 	{ | ||||
| 		BAN::Vector<BAN::String> result; | ||||
| 		if (index > 0) | ||||
| 			return result; | ||||
| 
 | ||||
| 		LockGuard _(m_lock); | ||||
| 		TRY(result.reserve(m_devices.size())); | ||||
| 		for (Device* device : m_devices) | ||||
| 			TRY(result.emplace_back(device->name())); | ||||
| 		return result; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,110 @@ | |||
| #include <kernel/DeviceManager.h> | ||||
| #include <kernel/LockGuard.h> | ||||
| #include <kernel/PCI.h> | ||||
| #include <kernel/Process.h> | ||||
| #include <kernel/Storage/ATAController.h> | ||||
| 
 | ||||
| namespace Kernel | ||||
| { | ||||
| 
 | ||||
| 	static DeviceManager* s_instance = nullptr; | ||||
| 
 | ||||
| 	void DeviceManager::initialize() | ||||
| 	{ | ||||
| 		ASSERT(s_instance == nullptr); | ||||
| 
 | ||||
| 		s_instance = new DeviceManager; | ||||
| 		ASSERT(s_instance != nullptr); | ||||
| 		 | ||||
| 		for (const auto& pci_device : PCI::get().devices()) | ||||
| 		{ | ||||
| 			switch (pci_device.class_code()) | ||||
| 			{ | ||||
| 				case 0x01: | ||||
| 				{ | ||||
| 					StorageController* controller = nullptr; | ||||
| 					switch (pci_device.subclass()) | ||||
| 					{ | ||||
| 						case 0x01: | ||||
| 							if (auto res = ATAController::create(pci_device); res.is_error()) | ||||
| 								dprintln("{}", res.error()); | ||||
| 							else | ||||
| 								controller = res.value(); | ||||
| 							break; | ||||
| 						default: | ||||
| 							dprintln("unsupported storage device (pci subclass {2H})", pci_device.subclass()); | ||||
| 							break; | ||||
| 					} | ||||
| 
 | ||||
| 					if (controller) | ||||
| 					{ | ||||
| 						s_instance->add_device(controller); | ||||
| 						for (auto* device : controller->devices()) | ||||
| 						{ | ||||
| 							s_instance->add_device(device); | ||||
| 							for (auto* partition : device->partitions()) | ||||
| 								s_instance->add_device(partition); | ||||
| 						} | ||||
| 					} | ||||
| 					break; | ||||
| 				} | ||||
| 				default: | ||||
| 					break; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		MUST(Process::create_kernel( | ||||
| 			[](void*) | ||||
| 			{ | ||||
| 				while (true) | ||||
| 				{ | ||||
| 					DeviceManager::get().update(); | ||||
| 					PIT::sleep(1); | ||||
| 				} | ||||
| 			}, nullptr) | ||||
| 		); | ||||
| 	} | ||||
| 
 | ||||
| 	DeviceManager& DeviceManager::get() | ||||
| 	{ | ||||
| 		ASSERT(s_instance); | ||||
| 		return *s_instance; | ||||
| 	} | ||||
| 
 | ||||
| 	void DeviceManager::update() | ||||
| 	{ | ||||
| 		LockGuard _(m_lock); | ||||
| 		for (Device* device : m_devices) | ||||
| 			device->update(); | ||||
| 	} | ||||
| 
 | ||||
| 	void DeviceManager::add_device(Device* device) | ||||
| 	{ | ||||
| 		LockGuard _(m_lock); | ||||
| 		MUST(m_devices.push_back(device)); | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::ErrorOr<BAN::RefPtr<Inode>> DeviceManager::read_directory_inode(BAN::StringView name) | ||||
| 	{ | ||||
| 		LockGuard _(m_lock); | ||||
| 		for (Device* device : m_devices) | ||||
| 			if (device->name() == name) | ||||
| 				return BAN::RefPtr<Inode>(device); | ||||
| 		return BAN::Error::from_errno(ENOENT); | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::ErrorOr<BAN::Vector<BAN::String>> DeviceManager::read_directory_entries(size_t index) | ||||
| 	{ | ||||
| 		BAN::Vector<BAN::String> result; | ||||
| 		if (index > 0) | ||||
| 			return result; | ||||
| 
 | ||||
| 		LockGuard _(m_lock); | ||||
| 		TRY(result.reserve(m_devices.size())); | ||||
| 		for (Device* device : m_devices) | ||||
| 			TRY(result.emplace_back(device->name())); | ||||
| 		return result; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
|  | @ -1,6 +1,6 @@ | |||
| #include <BAN/ScopeGuard.h> | ||||
| #include <BAN/StringView.h> | ||||
| #include <kernel/Device.h> | ||||
| #include <kernel/DeviceManager.h> | ||||
| #include <kernel/FS/Ext2.h> | ||||
| #include <kernel/FS/VirtualFileSystem.h> | ||||
| #include <kernel/LockGuard.h> | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include <BAN/Time.h> | ||||
| #include <BAN/ScopeGuard.h> | ||||
| #include <BAN/Time.h> | ||||
| #include <kernel/ACPI.h> | ||||
| #include <kernel/DeviceManager.h> | ||||
| #include <kernel/IDT.h> | ||||
| #include <kernel/Input/PS2Controller.h> | ||||
| #include <kernel/Input/PS2Keyboard.h> | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #include <kernel/ACPI.h> | ||||
| #include <kernel/Arch.h> | ||||
| #include <kernel/Debug.h> | ||||
| #include <kernel/DeviceManager.h> | ||||
| #include <kernel/FS/VirtualFileSystem.h> | ||||
| #include <kernel/GDT.h> | ||||
| #include <kernel/IDT.h> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue