diff options
| -rw-r--r-- | drivers/s390/char/sclp_vt220.c | 27 |
1 files changed, 7 insertions, 20 deletions
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 35707c04e613..62576af36f47 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
| @@ -71,9 +71,6 @@ static struct list_head sclp_vt220_outqueue; | |||
| 71 | /* Number of requests in outqueue */ | 71 | /* Number of requests in outqueue */ |
| 72 | static int sclp_vt220_outqueue_count; | 72 | static int sclp_vt220_outqueue_count; |
| 73 | 73 | ||
| 74 | /* Wait queue used to delay write requests while we've run out of buffers */ | ||
| 75 | static wait_queue_head_t sclp_vt220_waitq; | ||
| 76 | |||
| 77 | /* Timer used for delaying write requests to merge subsequent messages into | 74 | /* Timer used for delaying write requests to merge subsequent messages into |
| 78 | * a single buffer */ | 75 | * a single buffer */ |
| 79 | static struct timer_list sclp_vt220_timer; | 76 | static struct timer_list sclp_vt220_timer; |
| @@ -133,7 +130,6 @@ sclp_vt220_process_queue(struct sclp_vt220_request *request) | |||
| 133 | } while (request && __sclp_vt220_emit(request)); | 130 | } while (request && __sclp_vt220_emit(request)); |
| 134 | if (request == NULL && sclp_vt220_flush_later) | 131 | if (request == NULL && sclp_vt220_flush_later) |
| 135 | sclp_vt220_emit_current(); | 132 | sclp_vt220_emit_current(); |
| 136 | wake_up(&sclp_vt220_waitq); | ||
| 137 | /* Check if the tty needs a wake up call */ | 133 | /* Check if the tty needs a wake up call */ |
| 138 | if (sclp_vt220_tty != NULL) { | 134 | if (sclp_vt220_tty != NULL) { |
| 139 | tty_wakeup(sclp_vt220_tty); | 135 | tty_wakeup(sclp_vt220_tty); |
| @@ -383,7 +379,7 @@ sclp_vt220_timeout(unsigned long data) | |||
| 383 | */ | 379 | */ |
| 384 | static int | 380 | static int |
| 385 | __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule, | 381 | __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule, |
| 386 | int convertlf, int may_schedule) | 382 | int convertlf, int may_fail) |
| 387 | { | 383 | { |
| 388 | unsigned long flags; | 384 | unsigned long flags; |
| 389 | void *page; | 385 | void *page; |
| @@ -395,15 +391,14 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule, | |||
| 395 | overall_written = 0; | 391 | overall_written = 0; |
| 396 | spin_lock_irqsave(&sclp_vt220_lock, flags); | 392 | spin_lock_irqsave(&sclp_vt220_lock, flags); |
| 397 | do { | 393 | do { |
| 398 | /* Create a sclp output buffer if none exists yet */ | 394 | /* Create an sclp output buffer if none exists yet */ |
| 399 | if (sclp_vt220_current_request == NULL) { | 395 | if (sclp_vt220_current_request == NULL) { |
| 400 | while (list_empty(&sclp_vt220_empty)) { | 396 | while (list_empty(&sclp_vt220_empty)) { |
| 401 | spin_unlock_irqrestore(&sclp_vt220_lock, flags); | 397 | spin_unlock_irqrestore(&sclp_vt220_lock, flags); |
| 402 | if (in_interrupt() || !may_schedule) | 398 | if (may_fail) |
| 403 | sclp_sync_wait(); | 399 | goto out; |
| 404 | else | 400 | else |
| 405 | wait_event(sclp_vt220_waitq, | 401 | sclp_sync_wait(); |
| 406 | !list_empty(&sclp_vt220_empty)); | ||
| 407 | spin_lock_irqsave(&sclp_vt220_lock, flags); | 402 | spin_lock_irqsave(&sclp_vt220_lock, flags); |
| 408 | } | 403 | } |
| 409 | page = (void *) sclp_vt220_empty.next; | 404 | page = (void *) sclp_vt220_empty.next; |
| @@ -437,6 +432,7 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule, | |||
| 437 | add_timer(&sclp_vt220_timer); | 432 | add_timer(&sclp_vt220_timer); |
| 438 | } | 433 | } |
| 439 | spin_unlock_irqrestore(&sclp_vt220_lock, flags); | 434 | spin_unlock_irqrestore(&sclp_vt220_lock, flags); |
| 435 | out: | ||
| 440 | return overall_written; | 436 | return overall_written; |
| 441 | } | 437 | } |
| 442 | 438 | ||
| @@ -520,19 +516,11 @@ sclp_vt220_close(struct tty_struct *tty, struct file *filp) | |||
| 520 | * character to the tty device. If the kernel uses this routine, | 516 | * character to the tty device. If the kernel uses this routine, |
| 521 | * it must call the flush_chars() routine (if defined) when it is | 517 | * it must call the flush_chars() routine (if defined) when it is |
| 522 | * done stuffing characters into the driver. | 518 | * done stuffing characters into the driver. |
| 523 | * | ||
| 524 | * NOTE: include/linux/tty_driver.h specifies that a character should be | ||
| 525 | * ignored if there is no room in the queue. This driver implements a different | ||
| 526 | * semantic in that it will block when there is no more room left. | ||
| 527 | * | ||
| 528 | * FIXME: putchar can currently be called from BH and other non blocking | ||
| 529 | * handlers so this semantic isn't a good idea. | ||
| 530 | */ | 519 | */ |
| 531 | static int | 520 | static int |
| 532 | sclp_vt220_put_char(struct tty_struct *tty, unsigned char ch) | 521 | sclp_vt220_put_char(struct tty_struct *tty, unsigned char ch) |
| 533 | { | 522 | { |
| 534 | __sclp_vt220_write(&ch, 1, 0, 0, 1); | 523 | return __sclp_vt220_write(&ch, 1, 0, 0, 1); |
| 535 | return 1; | ||
| 536 | } | 524 | } |
| 537 | 525 | ||
| 538 | /* | 526 | /* |
| @@ -653,7 +641,6 @@ static int __init __sclp_vt220_init(void) | |||
| 653 | spin_lock_init(&sclp_vt220_lock); | 641 | spin_lock_init(&sclp_vt220_lock); |
| 654 | INIT_LIST_HEAD(&sclp_vt220_empty); | 642 | INIT_LIST_HEAD(&sclp_vt220_empty); |
| 655 | INIT_LIST_HEAD(&sclp_vt220_outqueue); | 643 | INIT_LIST_HEAD(&sclp_vt220_outqueue); |
| 656 | init_waitqueue_head(&sclp_vt220_waitq); | ||
| 657 | init_timer(&sclp_vt220_timer); | 644 | init_timer(&sclp_vt220_timer); |
| 658 | sclp_vt220_current_request = NULL; | 645 | sclp_vt220_current_request = NULL; |
| 659 | sclp_vt220_buffered_chars = 0; | 646 | sclp_vt220_buffered_chars = 0; |
