aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/speakup/selection.c14
-rw-r--r--drivers/tty/tty_buffer.c2
2 files changed, 13 insertions, 3 deletions
diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c
index f67941e78e4a..ca04d3669acc 100644
--- a/drivers/staging/speakup/selection.c
+++ b/drivers/staging/speakup/selection.c
@@ -5,6 +5,8 @@
5#include <linux/device.h> /* for dev_warn */ 5#include <linux/device.h> /* for dev_warn */
6#include <linux/selection.h> 6#include <linux/selection.h>
7#include <linux/workqueue.h> 7#include <linux/workqueue.h>
8#include <linux/tty.h>
9#include <linux/tty_flip.h>
8#include <asm/cmpxchg.h> 10#include <asm/cmpxchg.h>
9 11
10#include "speakup.h" 12#include "speakup.h"
@@ -135,8 +137,12 @@ static void __speakup_paste_selection(struct work_struct *work)
135 struct tty_struct *tty = xchg(&spw->tty, NULL); 137 struct tty_struct *tty = xchg(&spw->tty, NULL);
136 struct vc_data *vc = (struct vc_data *) tty->driver_data; 138 struct vc_data *vc = (struct vc_data *) tty->driver_data;
137 int pasted = 0, count; 139 int pasted = 0, count;
140 struct tty_ldisc *ld;
138 DECLARE_WAITQUEUE(wait, current); 141 DECLARE_WAITQUEUE(wait, current);
139 142
143 ld = tty_ldisc_ref_wait(tty);
144 tty_buffer_lock_exclusive(&vc->port);
145
140 add_wait_queue(&vc->paste_wait, &wait); 146 add_wait_queue(&vc->paste_wait, &wait);
141 while (sel_buffer && sel_buffer_lth > pasted) { 147 while (sel_buffer && sel_buffer_lth > pasted) {
142 set_current_state(TASK_INTERRUPTIBLE); 148 set_current_state(TASK_INTERRUPTIBLE);
@@ -145,13 +151,15 @@ static void __speakup_paste_selection(struct work_struct *work)
145 continue; 151 continue;
146 } 152 }
147 count = sel_buffer_lth - pasted; 153 count = sel_buffer_lth - pasted;
148 count = min_t(int, count, tty->receive_room); 154 count = tty_ldisc_receive_buf(ld, sel_buffer + pasted, NULL,
149 tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, 155 count);
150 NULL, count);
151 pasted += count; 156 pasted += count;
152 } 157 }
153 remove_wait_queue(&vc->paste_wait, &wait); 158 remove_wait_queue(&vc->paste_wait, &wait);
154 current->state = TASK_RUNNING; 159 current->state = TASK_RUNNING;
160
161 tty_buffer_unlock_exclusive(&vc->port);
162 tty_ldisc_deref(ld);
155 tty_kref_put(tty); 163 tty_kref_put(tty);
156} 164}
157 165
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index cf78d1985cd8..143deb62467d 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -60,6 +60,7 @@ void tty_buffer_lock_exclusive(struct tty_port *port)
60 atomic_inc(&buf->priority); 60 atomic_inc(&buf->priority);
61 mutex_lock(&buf->lock); 61 mutex_lock(&buf->lock);
62} 62}
63EXPORT_SYMBOL_GPL(tty_buffer_lock_exclusive);
63 64
64void tty_buffer_unlock_exclusive(struct tty_port *port) 65void tty_buffer_unlock_exclusive(struct tty_port *port)
65{ 66{
@@ -73,6 +74,7 @@ void tty_buffer_unlock_exclusive(struct tty_port *port)
73 if (restart) 74 if (restart)
74 queue_work(system_unbound_wq, &buf->work); 75 queue_work(system_unbound_wq, &buf->work);
75} 76}
77EXPORT_SYMBOL_GPL(tty_buffer_unlock_exclusive);
76 78
77/** 79/**
78 * tty_buffer_space_avail - return unused buffer space 80 * tty_buffer_space_avail - return unused buffer space