diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel/arch/i386/driver/ps2.c | 40 | ||||
-rw-r--r-- | src/kernel/arch/i386/driver/serial.c | 42 | ||||
-rw-r--r-- | src/kernel/util.h | 6 |
3 files changed, 32 insertions, 56 deletions
diff --git a/src/kernel/arch/i386/driver/ps2.c b/src/kernel/arch/i386/driver/ps2.c index aaa3156..b7e82eb 100644 --- a/src/kernel/arch/i386/driver/ps2.c +++ b/src/kernel/arch/i386/driver/ps2.c @@ -6,63 +6,47 @@ #include <shared/container/ring.h> #include <shared/mem.h> - #define BACKLOG_CAPACITY 64 static volatile uint8_t backlog_buf[BACKLOG_CAPACITY]; static volatile ring_t backlog = {(void*)backlog_buf, BACKLOG_CAPACITY, 0, 0}; -static struct vfs_request *blocked_on = NULL; - - 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_backend backend = BACKEND_KERN(is_ready, accept); void ps2_init(void) { vfs_mount_root_register("/ps2", &backend); } - -static bool ps2_ready(void) { - return ring_size((void*)&backlog) > 0; -} - void ps2_recv(uint8_t s) { ring_put1b((void*)&backlog, s); if (blocked_on) { accept(blocked_on); blocked_on = NULL; + vfs_backend_tryaccept(&backend); } } -static size_t ps2_read(uint8_t *buf, size_t len) { - return ring_get((void*)&backlog, buf, len); -} - static void accept(struct vfs_request *req) { // when you fix something here go also fix it in the COM1 driver static uint8_t buf[32]; // pretty damn stupid int ret; switch (req->type) { case VFSOP_OPEN: - // allows opening /ps2/anything, TODO don't - vfsreq_finish(req, 0); // fake file handle, whatever + ret = req->input.len == 0 ? 0 : -1; + vfsreq_finish(req, 0); break; case VFSOP_READ: - if (ps2_ready()) { - // TODO FUKKEN MESS - if (req->caller) { - // clamp between 0, sizeof buf - ret = req->output.len; - if (ret > (int)sizeof buf) ret = sizeof buf; - if (ret < 0) ret = 0; - - ret = ps2_read(buf, ret); - virt_cpy_to(req->caller->pages, req->output.buf, buf, ret); - } else ret = -1; + if (ring_size((void*)&backlog) == 0) { + // nothing to read + blocked_on = req; + } else if (req->caller) { + ret = clamp(0, req->output.len, sizeof buf); + ret = ring_get((void*)&backlog, buf, ret); + virt_cpy_to(req->caller->pages, req->output.buf, buf, ret); vfsreq_finish(req, ret); } else { - blocked_on = req; + vfsreq_finish(req, -1); } break; default: diff --git a/src/kernel/arch/i386/driver/serial.c b/src/kernel/arch/i386/driver/serial.c index 12cf2b8..cda016c 100644 --- a/src/kernel/arch/i386/driver/serial.c +++ b/src/kernel/arch/i386/driver/serial.c @@ -13,20 +13,14 @@ static volatile ring_t backlog = {(void*)backlog_buf, BACKLOG_CAPACITY, 0, 0}; static const int COM1 = 0x3f8; -static struct vfs_request *blocked_on = NULL; - - 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_backend backend = BACKEND_KERN(is_ready, accept); void serial_init(void) { vfs_mount_root_register("/com1", &backend); } - - - static void serial_selftest(void) { char b = 0x69; port_out8(COM1 + 4, 0b00011110); // enable loopback mode @@ -51,23 +45,15 @@ void serial_preinit(void) { } -static bool serial_ready(void) { - return ring_size((void*)&backlog) > 0; -} - void serial_irq(void) { ring_put1b((void*)&backlog, port_in8(COM1)); if (blocked_on) { accept(blocked_on); blocked_on = NULL; - // TODO vfs_backend_tryaccept + vfs_backend_tryaccept(&backend); } } -static size_t serial_read(char *buf, size_t len) { - return ring_get((void*)&backlog, buf, len); -} - static void serial_putchar(char c) { while ((port_in8(COM1 + 5) & 0x20) == 0); // wait for THRE @@ -85,22 +71,20 @@ static void accept(struct vfs_request *req) { int ret; switch (req->type) { case VFSOP_OPEN: + ret = req->input.len == 0 ? 0 : -1; vfsreq_finish(req, 0); break; case VFSOP_READ: - if (serial_ready()) { - if (req->caller) { - // clamp between 0, sizeof buf - ret = req->output.len; - if (ret > (int)sizeof buf) ret = sizeof buf; - if (ret < 0) ret = 0; - - ret = serial_read(buf, ret); - virt_cpy_to(req->caller->pages, req->output.buf, buf, ret); - } else ret = -1; + if (ring_size((void*)&backlog) == 0) { + // nothing to read + blocked_on = req; + } else if (req->caller) { + ret = clamp(0, req->output.len, sizeof buf); + ret = ring_get((void*)&backlog, buf, ret); + virt_cpy_to(req->caller->pages, req->output.buf, buf, ret); vfsreq_finish(req, ret); } else { - blocked_on = req; + vfsreq_finish(req, -1); } break; case VFSOP_WRITE: @@ -120,4 +104,6 @@ static void accept(struct vfs_request *req) { } } -static bool is_ready(struct vfs_backend __attribute__((unused)) *self) { return blocked_on == NULL; } +static bool is_ready(struct vfs_backend __attribute__((unused)) *self) { + return blocked_on == NULL; +} diff --git a/src/kernel/util.h b/src/kernel/util.h index 0e57d67..59af755 100644 --- a/src/kernel/util.h +++ b/src/kernel/util.h @@ -19,3 +19,9 @@ static inline int32_t capped_cast32(uint32_t u) { return (int32_t)min(u, (uint32_t)INT32_MAX); } + +static inline int clamp(int lo, int i, int hi) { + if (i < lo) return lo; + if (i > hi) return hi; + return i; +} |