diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/speakup/selection.c | 14 | ||||
-rw-r--r-- | drivers/tty/tty_buffer.c | 2 |
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 | } |
63 | EXPORT_SYMBOL_GPL(tty_buffer_lock_exclusive); | ||
63 | 64 | ||
64 | void tty_buffer_unlock_exclusive(struct tty_port *port) | 65 | void 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 | } |
77 | EXPORT_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 |