diff options
author | dzwdz | 2022-03-27 16:38:14 +0200 |
---|---|---|
committer | dzwdz | 2022-03-27 16:38:14 +0200 |
commit | b74ef85cce1ceb5840e9f3bdc43558b75740b83b (patch) | |
tree | cb347547182d708b370a6af411cad02bce23a847 /src/kernel/vfs | |
parent | 1fc26ce8e5b397f7301d783fbd4c776e5b5b5275 (diff) |
kernel/vfs: partial ATA drive support
Diffstat (limited to 'src/kernel/vfs')
-rw-r--r-- | src/kernel/vfs/root.c | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/src/kernel/vfs/root.c b/src/kernel/vfs/root.c index 9833330..e881ff2 100644 --- a/src/kernel/vfs/root.c +++ b/src/kernel/vfs/root.c @@ -1,3 +1,4 @@ +#include <kernel/arch/i386/ata.h> #include <kernel/mem/virt.h> #include <kernel/panic.h> #include <kernel/proc.h> @@ -5,10 +6,15 @@ #include <kernel/vfs/root.h> #include <shared/mem.h> +// TODO move to arch/ + enum { HANDLE_ROOT, HANDLE_TTY, HANDLE_VGA, + HANDLE_ATA_ROOT, + HANDLE_ATA, + _SKIP = HANDLE_ATA + 4, }; static bool exacteq(struct vfs_request *req, const char *str) { @@ -49,18 +55,29 @@ static void req_preprocess(struct vfs_request *req, int max_len) { int vfs_root_handler(struct vfs_request *req) { switch (req->type) { case VFSOP_OPEN: - if (exacteq(req, "/")) return HANDLE_ROOT; - if (exacteq(req, "/tty")) return HANDLE_TTY; - if (exacteq(req, "/vga")) return HANDLE_VGA; + if (exacteq(req, "/")) return HANDLE_ROOT; + if (exacteq(req, "/tty")) return HANDLE_TTY; + if (exacteq(req, "/vga")) return HANDLE_VGA; + if (exacteq(req, "/ata/")) return HANDLE_ATA_ROOT; + + if (exacteq(req, "/ata/0")) + return ata_available(0) ? HANDLE_ATA+0 : -1; + if (exacteq(req, "/ata/1")) + return ata_available(1) ? HANDLE_ATA+1 : -1; + if (exacteq(req, "/ata/2")) + return ata_available(2) ? HANDLE_ATA+2 : -1; + if (exacteq(req, "/ata/3")) + return ata_available(3) ? HANDLE_ATA+3 : -1; + return -1; case VFSOP_READ: switch (req->id) { case HANDLE_ROOT: { // TODO document directory read format - const char *src = "tty\0vga\0"; + const char src[] = "tty\0vga\0ata/"; if (req->output.len < 0) return 0; // is this needed? TODO make that a size_t or something - int len = min((size_t) req->output.len, strlen(src) + 1); + int len = min((size_t) req->output.len, sizeof(src)); virt_cpy_to(req->caller->pages, req->output.buf, src, len); return len; } @@ -79,6 +96,30 @@ int vfs_root_handler(struct vfs_request *req) { vga + req->offset, req->output.len); return req->output.len; } + case HANDLE_ATA_ROOT: { + // TODO offset + char list[8] = {}; + size_t len = 0; + for (int i = 0; i < 4; i++) { + if (ata_available(i)) { + list[len] = '0' + i; + len += 2; + } + } + len = min((size_t) req->output.len, len); + virt_cpy_to(req->caller->pages, req->output.buf, list, len); + return len; + } + case HANDLE_ATA: case HANDLE_ATA+1: + case HANDLE_ATA+2: case HANDLE_ATA+3: { + if (req->offset < 0) return 0; + char buf[512]; + uint32_t sector = req->offset / 512; + int len = min(req->output.len, 512 - (req->offset & 511)); + ata_read(req->id - HANDLE_ATA, sector, buf); + virt_cpy_to(req->caller->pages, req->output.buf, buf, len); + return len; + } default: panic_invalid_state(); } @@ -100,6 +141,7 @@ int vfs_root_handler(struct vfs_request *req) { req->input.buf, req->input.len); return req->input.len; } + case HANDLE_ATA_ROOT: return -1; default: panic_invalid_state(); } |