summaryrefslogtreecommitdiff
path: root/kernel/serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/serial.c')
-rw-r--r--kernel/serial.c58
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);
}