aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c68
1 files changed, 30 insertions, 38 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index bd74e82d8a72..8d19f7281f0b 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -267,7 +267,6 @@ static struct tty_buffer *tty_buffer_alloc(size_t size)
267 p->used = 0; 267 p->used = 0;
268 p->size = size; 268 p->size = size;
269 p->next = NULL; 269 p->next = NULL;
270 p->active = 0;
271 p->commit = 0; 270 p->commit = 0;
272 p->read = 0; 271 p->read = 0;
273 p->char_buf_ptr = (char *)(p->data); 272 p->char_buf_ptr = (char *)(p->data);
@@ -327,10 +326,9 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size)
327 /* OPTIMISATION: We could keep a per tty "zero" sized buffer to 326 /* OPTIMISATION: We could keep a per tty "zero" sized buffer to
328 remove this conditional if its worth it. This would be invisible 327 remove this conditional if its worth it. This would be invisible
329 to the callers */ 328 to the callers */
330 if ((b = tty->buf.tail) != NULL) { 329 if ((b = tty->buf.tail) != NULL)
331 left = b->size - b->used; 330 left = b->size - b->used;
332 b->active = 1; 331 else
333 } else
334 left = 0; 332 left = 0;
335 333
336 if (left < size) { 334 if (left < size) {
@@ -338,12 +336,10 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size)
338 if ((n = tty_buffer_find(tty, size)) != NULL) { 336 if ((n = tty_buffer_find(tty, size)) != NULL) {
339 if (b != NULL) { 337 if (b != NULL) {
340 b->next = n; 338 b->next = n;
341 b->active = 0;
342 b->commit = b->used; 339 b->commit = b->used;
343 } else 340 } else
344 tty->buf.head = n; 341 tty->buf.head = n;
345 tty->buf.tail = n; 342 tty->buf.tail = n;
346 n->active = 1;
347 } else 343 } else
348 size = left; 344 size = left;
349 } 345 }
@@ -404,10 +400,8 @@ void tty_schedule_flip(struct tty_struct *tty)
404{ 400{
405 unsigned long flags; 401 unsigned long flags;
406 spin_lock_irqsave(&tty->buf.lock, flags); 402 spin_lock_irqsave(&tty->buf.lock, flags);
407 if (tty->buf.tail != NULL) { 403 if (tty->buf.tail != NULL)
408 tty->buf.tail->active = 0;
409 tty->buf.tail->commit = tty->buf.tail->used; 404 tty->buf.tail->commit = tty->buf.tail->used;
410 }
411 spin_unlock_irqrestore(&tty->buf.lock, flags); 405 spin_unlock_irqrestore(&tty->buf.lock, flags);
412 schedule_delayed_work(&tty->buf.work, 1); 406 schedule_delayed_work(&tty->buf.work, 1);
413} 407}
@@ -784,11 +778,8 @@ restart:
784 } 778 }
785 779
786 clear_bit(TTY_LDISC, &tty->flags); 780 clear_bit(TTY_LDISC, &tty->flags);
787 clear_bit(TTY_DONT_FLIP, &tty->flags); 781 if (o_tty)
788 if (o_tty) {
789 clear_bit(TTY_LDISC, &o_tty->flags); 782 clear_bit(TTY_LDISC, &o_tty->flags);
790 clear_bit(TTY_DONT_FLIP, &o_tty->flags);
791 }
792 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 783 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
793 784
794 /* 785 /*
@@ -1955,7 +1946,6 @@ static void release_dev(struct file * filp)
1955 * race with the set_ldisc code path. 1946 * race with the set_ldisc code path.
1956 */ 1947 */
1957 clear_bit(TTY_LDISC, &tty->flags); 1948 clear_bit(TTY_LDISC, &tty->flags);
1958 clear_bit(TTY_DONT_FLIP, &tty->flags);
1959 cancel_delayed_work(&tty->buf.work); 1949 cancel_delayed_work(&tty->buf.work);
1960 1950
1961 /* 1951 /*
@@ -2775,8 +2765,7 @@ static void flush_to_ldisc(void *private_)
2775 struct tty_struct *tty = (struct tty_struct *) private_; 2765 struct tty_struct *tty = (struct tty_struct *) private_;
2776 unsigned long flags; 2766 unsigned long flags;
2777 struct tty_ldisc *disc; 2767 struct tty_ldisc *disc;
2778 struct tty_buffer *tbuf; 2768 struct tty_buffer *tbuf, *head;
2779 int count;
2780 char *char_buf; 2769 char *char_buf;
2781 unsigned char *flag_buf; 2770 unsigned char *flag_buf;
2782 2771
@@ -2784,32 +2773,37 @@ static void flush_to_ldisc(void *private_)
2784 if (disc == NULL) /* !TTY_LDISC */ 2773 if (disc == NULL) /* !TTY_LDISC */
2785 return; 2774 return;
2786 2775
2787 if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
2788 /*
2789 * Do it after the next timer tick:
2790 */
2791 schedule_delayed_work(&tty->buf.work, 1);
2792 goto out;
2793 }
2794 spin_lock_irqsave(&tty->buf.lock, flags); 2776 spin_lock_irqsave(&tty->buf.lock, flags);
2795 while((tbuf = tty->buf.head) != NULL) { 2777 head = tty->buf.head;
2796 while ((count = tbuf->commit - tbuf->read) != 0) { 2778 if (head != NULL) {
2797 char_buf = tbuf->char_buf_ptr + tbuf->read; 2779 tty->buf.head = NULL;
2798 flag_buf = tbuf->flag_buf_ptr + tbuf->read; 2780 for (;;) {
2799 tbuf->read += count; 2781 int count = head->commit - head->read;
2782 if (!count) {
2783 if (head->next == NULL)
2784 break;
2785 tbuf = head;
2786 head = head->next;
2787 tty_buffer_free(tty, tbuf);
2788 continue;
2789 }
2790 if (!tty->receive_room) {
2791 schedule_delayed_work(&tty->buf.work, 1);
2792 break;
2793 }
2794 if (count > tty->receive_room)
2795 count = tty->receive_room;
2796 char_buf = head->char_buf_ptr + head->read;
2797 flag_buf = head->flag_buf_ptr + head->read;
2798 head->read += count;
2800 spin_unlock_irqrestore(&tty->buf.lock, flags); 2799 spin_unlock_irqrestore(&tty->buf.lock, flags);
2801 disc->receive_buf(tty, char_buf, flag_buf, count); 2800 disc->receive_buf(tty, char_buf, flag_buf, count);
2802 spin_lock_irqsave(&tty->buf.lock, flags); 2801 spin_lock_irqsave(&tty->buf.lock, flags);
2803 } 2802 }
2804 if (tbuf->active) 2803 tty->buf.head = head;
2805 break;
2806 tty->buf.head = tbuf->next;
2807 if (tty->buf.head == NULL)
2808 tty->buf.tail = NULL;
2809 tty_buffer_free(tty, tbuf);
2810 } 2804 }
2811 spin_unlock_irqrestore(&tty->buf.lock, flags); 2805 spin_unlock_irqrestore(&tty->buf.lock, flags);
2812out: 2806
2813 tty_ldisc_deref(disc); 2807 tty_ldisc_deref(disc);
2814} 2808}
2815 2809
@@ -2902,10 +2896,8 @@ void tty_flip_buffer_push(struct tty_struct *tty)
2902{ 2896{
2903 unsigned long flags; 2897 unsigned long flags;
2904 spin_lock_irqsave(&tty->buf.lock, flags); 2898 spin_lock_irqsave(&tty->buf.lock, flags);
2905 if (tty->buf.tail != NULL) { 2899 if (tty->buf.tail != NULL)
2906 tty->buf.tail->active = 0;
2907 tty->buf.tail->commit = tty->buf.tail->used; 2900 tty->buf.tail->commit = tty->buf.tail->used;
2908 }
2909 spin_unlock_irqrestore(&tty->buf.lock, flags); 2901 spin_unlock_irqrestore(&tty->buf.lock, flags);
2910 2902
2911 if (tty->low_latency) 2903 if (tty->low_latency)