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