diff options
Diffstat (limited to 'kernel/serial.c')
| -rw-r--r-- | kernel/serial.c | 58 |
1 files changed, 13 insertions, 45 deletions
diff --git a/kernel/serial.c b/kernel/serial.c index f5610f5..39c5ee0 100644 --- a/kernel/serial.c +++ b/kernel/serial.c @@ -3,6 +3,8 @@ #include <errno.h> #include <kernel/con.h> #include <kernel/sched.h> +#include <kernel/serial.h> +#include <kernel/tty.h> #include <sys/types.h> #include <unistd.h> @@ -25,11 +27,11 @@ extern void rs_isr(void); -static char present; +struct tty_struct tty_rs = { + .init = &serial_init +}; -static char rxbuf[256]; -static unsigned rxread, rxwrite; -static struct task_struct *waiting_task; +static char present; int rsputs(char *s) { if(!present) @@ -80,53 +82,19 @@ void serial_init(void) { rsputs("[kernel] Serial monitor initialized!\n\r"); printk("[rs] Serial port COM0 initialized!\n"); - rxread = 0; - rxwrite = 1; - waiting_task = NULL; present = 1; } -ssize_t rsread(void *buf, size_t len) { - ssize_t n = len; - char *b = buf; - - if(!present) - return -ENXIO; - - if(len == 0) - return 0; - - while(n--) { - /* check if the buffer's empty and if so, go to sleep */ - cli(); - if(rxread == rxwrite) - interruptible_sleep_on(&waiting_task); - - /* check again to see if anything was read, or we were interrupted */ - if(rxread == rxwrite) { - sti(); - return -EINTR; - } - - sti(); - - *b++ = rxbuf[rxread]; - rxread = rxread + 1 % sizeof(rxbuf); - } - - return len; -} - void rs_handler(void) { + struct tty_queue *q = &tty_rs.rqueue; + if((inb(RSLINES) & 1) == 0) return; - if(rxwrite == (rxread - 1 % sizeof(rxbuf))) + if(q->pwrite == (q->pread - 1 % sizeof(q->buf))) return; - rxbuf[rxwrite] = inb(RSDATA); - rxwrite = rxwrite + 1 % sizeof(rxbuf); - if(waiting_task != NULL) { - waiting_task->state = TSTATE_RUNNING; - waiting_task = NULL; - } + q->buf[q->pwrite] = inb(RSDATA); + q->pwrite = q->pwrite + 1 % sizeof(q->buf); + + wake_up(&q->waiting); } |
