aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/tty/tty_buffer.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index a42a028a9d4e..6c7a1d043c76 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -403,6 +403,18 @@ int tty_prepare_flip_string_flags(struct tty_port *port,
EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
+static int
+receive_buf(struct tty_struct *tty, struct tty_buffer *head, int count)
+{
+ struct tty_ldisc *disc = tty->ldisc;
+
+ count = min_t(int, count, tty->receive_room);
+ if (count)
+ disc->ops->receive_buf(tty, head->char_buf_ptr + head->read,
+ head->flag_buf_ptr + head->read, count);
+ head->read += count;
+ return count;
+}
/**
* flush_to_ldisc
@@ -438,8 +450,6 @@ static void flush_to_ldisc(struct work_struct *work)
struct tty_buffer *head;
while ((head = buf->head) != NULL) {
int count;
- char *char_buf;
- unsigned char *flag_buf;
count = head->commit - head->read;
if (!count) {
@@ -449,16 +459,10 @@ static void flush_to_ldisc(struct work_struct *work)
tty_buffer_free(port, head);
continue;
}
- if (!tty->receive_room)
- break;
- if (count > tty->receive_room)
- count = tty->receive_room;
- char_buf = head->char_buf_ptr + head->read;
- flag_buf = head->flag_buf_ptr + head->read;
- head->read += count;
spin_unlock_irqrestore(&buf->lock, flags);
- disc->ops->receive_buf(tty, char_buf,
- flag_buf, count);
+
+ count = receive_buf(tty, head, count);
+
spin_lock_irqsave(&buf->lock, flags);
/* Ldisc or user is trying to flush the buffers.
We may have a deferred request to flush the
@@ -469,7 +473,8 @@ static void flush_to_ldisc(struct work_struct *work)
clear_bit(TTYP_FLUSHPENDING, &port->iflags);
wake_up(&tty->read_wait);
break;
- }
+ } else if (!count)
+ break;
}
clear_bit(TTYP_FLUSHING, &port->iflags);
}