diff options
| -rw-r--r-- | drivers/s390/char/sclp_tty.c | 36 |
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; | |||
| 48 | static struct sclp_buffer *sclp_ttybuf; | 47 | static struct sclp_buffer *sclp_ttybuf; |
| 49 | /* Timer for delayed output of console messages. */ | 48 | /* Timer for delayed output of console messages. */ |
| 50 | static struct timer_list sclp_tty_timer; | 49 | static struct timer_list sclp_tty_timer; |
| 51 | /* Waitqueue to wait for buffers to get empty. */ | ||
| 52 | static wait_queue_head_t sclp_tty_waitq; | ||
| 53 | 50 | ||
| 54 | static struct tty_struct *sclp_tty; | 51 | static struct tty_struct *sclp_tty; |
| 55 | static unsigned char sclp_tty_chars[SCLP_TTY_BUF_SIZE]; | 52 | static 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 | */ |
| 179 | static void | 175 | static int sclp_tty_write_string(const unsigned char *str, int count, int may_fail) |
| 180 | sclp_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); |
| 231 | out: | ||
| 232 | return overall_written; | ||
| 234 | } | 233 | } |
| 235 | 234 | ||
| 236 | /* | 235 | /* |
| @@ -242,11 +241,10 @@ static int | |||
| 242 | sclp_tty_write(struct tty_struct *tty, const unsigned char *buf, int count) | 241 | sclp_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 | |||
| 277 | sclp_tty_flush_chars(struct tty_struct *tty) | 276 | sclp_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 | |||
| 316 | sclp_tty_flush_buffer(struct tty_struct *tty) | 315 | sclp_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; |
