diff options
Diffstat (limited to 'kernel/tty.c')
| -rw-r--r-- | kernel/tty.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/kernel/tty.c b/kernel/tty.c index 75c3701..bfbf775 100644 --- a/kernel/tty.c +++ b/kernel/tty.c @@ -35,14 +35,24 @@ static int sleep_while_empty(struct tty_queue *q) { } /* check if a buffer's full and if so, go to sleep */ -static int sleep_while_full(struct tty_queue *q) { +static int sleep_while_full(struct tty_queue *q, struct tty_struct *tty) { cli(); while(1) { - if(q->pwrite == (q->pread - 1 % sizeof(q->buf))) + /* + * if the buffer is full, first notify the + * driver so it can try to remove some + * data then, check again and if it's + * still full, go to sleep. + */ + if(q->pwrite == ((q->pread - 1) % sizeof(q->buf))) + if(tty->write) + tty->write(); + + if(q->pwrite == ((q->pread - 1) % sizeof(q->buf))) interruptible_sleep_on(&q->waiting); /* check again to see if anything was removed, or we were interrupted */ - if(q->pwrite == (q->pread - 1 % sizeof(q->buf))) { + if(q->pwrite == ((q->pread - 1) % sizeof(q->buf))) { sti(); return -1; } @@ -98,7 +108,7 @@ ssize_t tty_write(unsigned tty, void *buf, size_t len) { for(i = 0; i < len; i++) { /* check if the buffer's full and if so, go to sleep */ - if(sleep_while_full(q) < 0) { + if(sleep_while_full(q, ttys[tty]) < 0) { if(i == 0) return -EINTR; |
