aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/char')
-rw-r--r--drivers/s390/char/sclp_tty.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index bcf691af5336..434ba04b1309 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -13,7 +13,6 @@
13#include <linux/tty.h> 13#include <linux/tty.h>
14#include <linux/tty_driver.h> 14#include <linux/tty_driver.h>
15#include <linux/tty_flip.h> 15#include <linux/tty_flip.h>
16#include <linux/wait.h>
17#include <linux/slab.h> 16#include <linux/slab.h>
18#include <linux/err.h> 17#include <linux/err.h>
19#include <linux/init.h> 18#include <linux/init.h>
@@ -48,8 +47,6 @@ static int sclp_tty_buffer_count;
48static struct sclp_buffer *sclp_ttybuf; 47static struct sclp_buffer *sclp_ttybuf;
49/* Timer for delayed output of console messages. */ 48/* Timer for delayed output of console messages. */
50static struct timer_list sclp_tty_timer; 49static struct timer_list sclp_tty_timer;
51/* Waitqueue to wait for buffers to get empty. */
52static wait_queue_head_t sclp_tty_waitq;
53 50
54static struct tty_struct *sclp_tty; 51static struct tty_struct *sclp_tty;
55static unsigned char sclp_tty_chars[SCLP_TTY_BUF_SIZE]; 52static unsigned char sclp_tty_chars[SCLP_TTY_BUF_SIZE];
@@ -128,7 +125,6 @@ sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc)
128 struct sclp_buffer, list); 125 struct sclp_buffer, list);
129 spin_unlock_irqrestore(&sclp_tty_lock, flags); 126 spin_unlock_irqrestore(&sclp_tty_lock, flags);
130 } while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback)); 127 } while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback));
131 wake_up(&sclp_tty_waitq);
132 /* check if the tty needs a wake up call */ 128 /* check if the tty needs a wake up call */
133 if (sclp_tty != NULL) { 129 if (sclp_tty != NULL) {
134 tty_wakeup(sclp_tty); 130 tty_wakeup(sclp_tty);
@@ -176,27 +172,27 @@ sclp_tty_timeout(unsigned long data)
176/* 172/*
177 * Write a string to the sclp tty. 173 * Write a string to the sclp tty.
178 */ 174 */
179static void 175static int sclp_tty_write_string(const unsigned char *str, int count, int may_fail)
180sclp_tty_write_string(const unsigned char *str, int count)
181{ 176{
182 unsigned long flags; 177 unsigned long flags;
183 void *page; 178 void *page;
184 int written; 179 int written;
180 int overall_written;
185 struct sclp_buffer *buf; 181 struct sclp_buffer *buf;
186 182
187 if (count <= 0) 183 if (count <= 0)
188 return; 184 return 0;
185 overall_written = 0;
189 spin_lock_irqsave(&sclp_tty_lock, flags); 186 spin_lock_irqsave(&sclp_tty_lock, flags);
190 do { 187 do {
191 /* Create a sclp output buffer if none exists yet */ 188 /* Create a sclp output buffer if none exists yet */
192 if (sclp_ttybuf == NULL) { 189 if (sclp_ttybuf == NULL) {
193 while (list_empty(&sclp_tty_pages)) { 190 while (list_empty(&sclp_tty_pages)) {
194 spin_unlock_irqrestore(&sclp_tty_lock, flags); 191 spin_unlock_irqrestore(&sclp_tty_lock, flags);
195 if (in_interrupt()) 192 if (may_fail)
196 sclp_sync_wait(); 193 goto out;
197 else 194 else
198 wait_event(sclp_tty_waitq, 195 sclp_sync_wait();
199 !list_empty(&sclp_tty_pages));
200 spin_lock_irqsave(&sclp_tty_lock, flags); 196 spin_lock_irqsave(&sclp_tty_lock, flags);
201 } 197 }
202 page = sclp_tty_pages.next; 198 page = sclp_tty_pages.next;
@@ -206,6 +202,7 @@ sclp_tty_write_string(const unsigned char *str, int count)
206 } 202 }
207 /* try to write the string to the current output buffer */ 203 /* try to write the string to the current output buffer */
208 written = sclp_write(sclp_ttybuf, str, count); 204 written = sclp_write(sclp_ttybuf, str, count);
205 overall_written += written;
209 if (written == count) 206 if (written == count)
210 break; 207 break;
211 /* 208 /*
@@ -231,6 +228,8 @@ sclp_tty_write_string(const unsigned char *str, int count)
231 add_timer(&sclp_tty_timer); 228 add_timer(&sclp_tty_timer);
232 } 229 }
233 spin_unlock_irqrestore(&sclp_tty_lock, flags); 230 spin_unlock_irqrestore(&sclp_tty_lock, flags);
231out:
232 return overall_written;
234} 233}
235 234
236/* 235/*
@@ -242,11 +241,10 @@ static int
242sclp_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) 241sclp_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
243{ 242{
244 if (sclp_tty_chars_count > 0) { 243 if (sclp_tty_chars_count > 0) {
245 sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count); 244 sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count, 0);
246 sclp_tty_chars_count = 0; 245 sclp_tty_chars_count = 0;
247 } 246 }
248 sclp_tty_write_string(buf, count); 247 return sclp_tty_write_string(buf, count, 1);
249 return count;
250} 248}
251 249
252/* 250/*
@@ -264,9 +262,10 @@ sclp_tty_put_char(struct tty_struct *tty, unsigned char ch)
264{ 262{
265 sclp_tty_chars[sclp_tty_chars_count++] = ch; 263 sclp_tty_chars[sclp_tty_chars_count++] = ch;
266 if (ch == '\n' || sclp_tty_chars_count >= SCLP_TTY_BUF_SIZE) { 264 if (ch == '\n' || sclp_tty_chars_count >= SCLP_TTY_BUF_SIZE) {
267 sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count); 265 sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count, 0);
268 sclp_tty_chars_count = 0; 266 sclp_tty_chars_count = 0;
269 } return 1; 267 }
268 return 1;
270} 269}
271 270
272/* 271/*
@@ -277,7 +276,7 @@ static void
277sclp_tty_flush_chars(struct tty_struct *tty) 276sclp_tty_flush_chars(struct tty_struct *tty)
278{ 277{
279 if (sclp_tty_chars_count > 0) { 278 if (sclp_tty_chars_count > 0) {
280 sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count); 279 sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count, 0);
281 sclp_tty_chars_count = 0; 280 sclp_tty_chars_count = 0;
282 } 281 }
283} 282}
@@ -316,7 +315,7 @@ static void
316sclp_tty_flush_buffer(struct tty_struct *tty) 315sclp_tty_flush_buffer(struct tty_struct *tty)
317{ 316{
318 if (sclp_tty_chars_count > 0) { 317 if (sclp_tty_chars_count > 0) {
319 sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count); 318 sclp_tty_write_string(sclp_tty_chars, sclp_tty_chars_count, 0);
320 sclp_tty_chars_count = 0; 319 sclp_tty_chars_count = 0;
321 } 320 }
322} 321}
@@ -577,7 +576,6 @@ sclp_tty_init(void)
577 } 576 }
578 INIT_LIST_HEAD(&sclp_tty_outqueue); 577 INIT_LIST_HEAD(&sclp_tty_outqueue);
579 spin_lock_init(&sclp_tty_lock); 578 spin_lock_init(&sclp_tty_lock);
580 init_waitqueue_head(&sclp_tty_waitq);
581 init_timer(&sclp_tty_timer); 579 init_timer(&sclp_tty_timer);
582 sclp_ttybuf = NULL; 580 sclp_ttybuf = NULL;
583 sclp_tty_buffer_count = 0; 581 sclp_tty_buffer_count = 0;