diff --git a/kernel/include/fs/devfs.hpp b/kernel/include/fs/devfs.hpp index 8778d112..a19feb18 100644 --- a/kernel/include/fs/devfs.hpp +++ b/kernel/include/fs/devfs.hpp @@ -16,6 +16,15 @@ namespace devfs { +enum class device_type { + BLOCK_DEVICE +}; + +struct dev_driver { + virtual size_t read(void* data, char* buffer, size_t count, size_t offset, size_t& read) = 0; + virtual size_t write(void* data, const char* buffer, size_t count, size_t offset, size_t& written) = 0; +}; + struct devfs_file_system : vfs::file_system { private: std::string mount_point; @@ -35,6 +44,9 @@ public: size_t rm(const std::vector& file_path); }; +void register_device(const std::string& mp, const std::string& name, device_type type, dev_driver* driver, void* data); +void deregister_device(const std::string& mp, const std::string& name); + } #endif diff --git a/kernel/src/fs/devfs.cpp b/kernel/src/fs/devfs.cpp index 1c43e217..ec36d784 100644 --- a/kernel/src/fs/devfs.cpp +++ b/kernel/src/fs/devfs.cpp @@ -16,6 +16,26 @@ namespace { +struct device { + std::string name; + devfs::device_type type; + devfs::dev_driver* driver; + void* data; + + device(){} + device(std::string name, devfs::device_type type, devfs::dev_driver* driver, void* data) + : name(name), type(type), driver(driver), data(data) {} +}; + +struct device_list { + std::string name; + std::vector devices; + + device_list(){}; + device_list(std::string name) : name(name){} +}; + +std::vector devices; } //end of anonymous namespace @@ -28,23 +48,105 @@ devfs::devfs_file_system::~devfs_file_system(){ } size_t devfs::devfs_file_system::get_file(const std::vector& file_path, vfs::file& f){ - //TODO + if(file_path.empty()){ + f.file_name = "/"; + f.directory = true; + f.hidden = false; + f.system = false; + f.size = 0; + + return 0; + } + + //No subfolder support + if(file_path.size() > 1){ + return std::ERROR_NOT_EXISTS; + } + + for(auto& device_list : devices){ + if(device_list.name == mount_point){ + for(auto& device : device_list.devices){ + if(device.name == file_path.back()){ + f.file_name = device.name; + f.directory = false; + f.hidden = false; + f.system = false; + f.size = 0; + + return 0; + } + } + } + } + + return std::ERROR_NOT_EXISTS; } size_t devfs::devfs_file_system::read(const std::vector& file_path, char* buffer, size_t count, size_t offset, size_t& read){ - //TODO + //Cannot access the root for reading + if(file_path.empty()){ + return std::ERROR_PERMISSION_DENIED; + } + + for(auto& device_list : devices){ + if(device_list.name == mount_point){ + for(auto& device : device_list.devices){ + if(device.name == file_path.back()){ + return device.driver->read(device.data, buffer, count, offset, read); + } + } + } + } + + return std::ERROR_NOT_EXISTS; } -size_t devfs::devfs_file_system::write(const std::vector&, const char*, size_t, size_t, size_t&){ - //TODO +size_t devfs::devfs_file_system::write(const std::vector& file_path, const char* buffer, size_t count, size_t offset, size_t& written){ + //Cannot access the root for writing + if(file_path.empty()){ + return std::ERROR_PERMISSION_DENIED; + } + + for(auto& device_list : devices){ + if(device_list.name == mount_point){ + for(auto& device : device_list.devices){ + if(device.name == file_path.back()){ + return device.driver->write(device.data, buffer, count, offset, written); + } + } + } + } + + return std::ERROR_NOT_EXISTS; } -size_t devfs::devfs_file_system::truncate(const std::vector& file_path, size_t size){ +size_t devfs::devfs_file_system::truncate(const std::vector&, size_t){ return std::ERROR_PERMISSION_DENIED; } size_t devfs::devfs_file_system::ls(const std::vector& file_path, std::vector& contents){ - //TODO + //No subfolder support + if(file_path.size() > 0){ + return std::ERROR_NOT_EXISTS; + } + + for(auto& device_list : devices){ + if(device_list.name == mount_point){ + for(auto& device : device_list.devices){ + vfs::file f; + f.file_name = device.name; + f.directory = false; + f.hidden = false; + f.system = false; + f.size = 0; + contents.emplace_back(std::move(f)); + } + + break; + } + } + + return 0; } size_t devfs::devfs_file_system::touch(const std::vector& ){ @@ -66,3 +168,29 @@ size_t devfs::devfs_file_system::statfs(statfs_info& file){ return 0; } +void devfs::register_device(const std::string& mp, const std::string& name, device_type type, dev_driver* driver, void* data){ + for(auto& device_list : devices){ + if(device_list.name == mp){ + device_list.devices.emplace_back(name, type, driver, data); + return; + } + } + + devices.emplace_back(mp); + devices.back().devices.emplace_back(name, type, driver, data); +} + +void devfs::deregister_device(const std::string& mp, const std::string& name){ + for(auto& device_list : devices){ + if(device_list.name == mp){ + for(size_t i = 0; i < device_list.devices.size(); ++i){ + if(device_list.devices[i].name == name){ + device_list.devices.erase(i); + break; + } + } + + return; + } + } +}