diff options
author | dzwdz | 2022-08-07 19:16:15 +0200 |
---|---|---|
committer | dzwdz | 2022-08-07 19:16:15 +0200 |
commit | fbbe8a1cb4c421e9658c5009ecfab6845137587b (patch) | |
tree | d5516a90539d8da30d6ceed71b465235d01e8985 /src/kernel/arch/amd64/driver | |
parent | eb36d836458803b5dcfa668fef487c52e5c45cdc (diff) |
driver/ps2: prepare for mouse support
Diffstat (limited to 'src/kernel/arch/amd64/driver')
-rw-r--r-- | src/kernel/arch/amd64/driver/fsroot.c | 2 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/ps2.c | 55 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/serial.c | 2 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/util.h | 1 |
4 files changed, 41 insertions, 19 deletions
diff --git a/src/kernel/arch/amd64/driver/fsroot.c b/src/kernel/arch/amd64/driver/fsroot.c index 0970d0b..98880fe 100644 --- a/src/kernel/arch/amd64/driver/fsroot.c +++ b/src/kernel/arch/amd64/driver/fsroot.c @@ -48,7 +48,7 @@ static int handle(struct vfs_request *req) { // TODO don't hardcode const char src[] = "com1\0" - "ps2\0" + "ps2/\0" "ata/\0" "video/"; return req_readcopy(req, src, sizeof src); diff --git a/src/kernel/arch/amd64/driver/ps2.c b/src/kernel/arch/amd64/driver/ps2.c index e3aaef8..7ed369b 100644 --- a/src/kernel/arch/amd64/driver/ps2.c +++ b/src/kernel/arch/amd64/driver/ps2.c @@ -1,9 +1,11 @@ #include <kernel/arch/amd64/driver/ps2.h> +#include <kernel/arch/amd64/driver/util.h> #include <kernel/arch/amd64/interrupts/irq.h> #include <kernel/arch/amd64/port_io.h> #include <kernel/panic.h> #include <kernel/ring.h> #include <kernel/vfs/request.h> +#include <shared/mem.h> static volatile uint8_t backlog_buf[64]; static volatile ring_t backlog = {(void*)backlog_buf, sizeof backlog_buf, 0, 0}; @@ -11,41 +13,60 @@ static volatile ring_t backlog = {(void*)backlog_buf, sizeof backlog_buf, 0, 0}; static void accept(struct vfs_request *req); static bool is_ready(struct vfs_backend *self); -static struct vfs_request *blocked_on = NULL; +static struct vfs_request *kb_queue = NULL; static struct vfs_backend backend = BACKEND_KERN(is_ready, accept); void ps2_init(void) { vfs_mount_root_register("/ps2", &backend); } void ps2_irq(void) { ring_put1b((void*)&backlog, port_in8(0x60)); - if (blocked_on) { - accept(blocked_on); - blocked_on = NULL; + if (kb_queue) { + accept(kb_queue); + kb_queue = kb_queue->postqueue_next; vfs_backend_tryaccept(&backend); } } +enum { + H_ROOT, + H_KB, +}; + static void accept(struct vfs_request *req) { // when you fix something here go also fix it in the COM1 driver int ret; - bool valid; switch (req->type) { case VFSOP_OPEN: - valid = req->input.len == 0; - vfsreq_finish_short(req, valid ? 0 : -1); - break; - case VFSOP_READ: - if (ring_size((void*)&backlog) == 0) { - // nothing to read - blocked_on = req; - } else if (req->caller) { - if (ret < 0) ret = 0; - ret = ring_to_virt((void*)&backlog, req->caller->pages, req->output.buf, req->output.len); - vfsreq_finish_short(req, ret); + if (!req->input.kern) panic_invalid_state(); + if (req->input.len == 1) { + vfsreq_finish_short(req, H_ROOT); + } else if (req->input.len == 3 && !memcmp(req->input.buf_kern, "/kb", 3)) { + vfsreq_finish_short(req, H_KB); } else { vfsreq_finish_short(req, -1); } break; + case VFSOP_READ: + if ((long __force)req->id == H_ROOT) { + const char data[] = "kb"; + ret = req_readcopy(req, data, sizeof data); + vfsreq_finish_short(req, ret); + } else if ((long __force)req->id == H_KB) { + if (ring_size((void*)&backlog) == 0) { + /* nothing to read, join queue */ + assert(!req->postqueue_next); + struct vfs_request **slot = &kb_queue; + while (*slot) slot = &(*slot)->postqueue_next; + *slot = req; + } else if (req->caller) { + if (ret < 0) ret = 0; + ret = ring_to_virt((void*)&backlog, req->caller->pages, req->output.buf, req->output.len); + vfsreq_finish_short(req, ret); + } else { + vfsreq_finish_short(req, -1); + } + } else panic_invalid_state(); + break; default: vfsreq_finish_short(req, -1); break; @@ -53,5 +74,5 @@ static void accept(struct vfs_request *req) { } static bool is_ready(struct vfs_backend __attribute__((unused)) *self) { - return blocked_on == NULL; + return true; } diff --git a/src/kernel/arch/amd64/driver/serial.c b/src/kernel/arch/amd64/driver/serial.c index 1401642..d8ee90b 100644 --- a/src/kernel/arch/amd64/driver/serial.c +++ b/src/kernel/arch/amd64/driver/serial.c @@ -47,7 +47,7 @@ void serial_irq(void) { ring_put1b((void*)&backlog, port_in8(COM1)); if (blocked_on) { accept(blocked_on); - blocked_on = NULL; + blocked_on = blocked_on->postqueue_next; vfs_backend_tryaccept(&backend); } } diff --git a/src/kernel/arch/amd64/driver/util.h b/src/kernel/arch/amd64/driver/util.h index fd8d506..bfdd25c 100644 --- a/src/kernel/arch/amd64/driver/util.h +++ b/src/kernel/arch/amd64/driver/util.h @@ -1,4 +1,5 @@ #pragma once +#include <stddef.h> struct vfs_request; int req_readcopy(struct vfs_request *req, const void *buf, size_t len); |