diff options
Diffstat (limited to 'drivers/s390/char')
-rw-r--r-- | drivers/s390/char/raw3270.c | 9 | ||||
-rw-r--r-- | drivers/s390/char/sclp_config.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_vt220.c | 28 | ||||
-rw-r--r-- | drivers/s390/char/tape.h | 3 | ||||
-rw-r--r-- | drivers/s390/char/tape_3590.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/tape_block.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/tape_core.c | 16 |
7 files changed, 26 insertions, 38 deletions
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 0d98f1ff2edd..848ef7e8523f 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c | |||
@@ -549,7 +549,6 @@ raw3270_start_init(struct raw3270 *rp, struct raw3270_view *view, | |||
549 | struct raw3270_request *rq) | 549 | struct raw3270_request *rq) |
550 | { | 550 | { |
551 | unsigned long flags; | 551 | unsigned long flags; |
552 | wait_queue_head_t wq; | ||
553 | int rc; | 552 | int rc; |
554 | 553 | ||
555 | #ifdef CONFIG_TN3270_CONSOLE | 554 | #ifdef CONFIG_TN3270_CONSOLE |
@@ -566,20 +565,20 @@ raw3270_start_init(struct raw3270 *rp, struct raw3270_view *view, | |||
566 | return rq->rc; | 565 | return rq->rc; |
567 | } | 566 | } |
568 | #endif | 567 | #endif |
569 | init_waitqueue_head(&wq); | ||
570 | rq->callback = raw3270_wake_init; | 568 | rq->callback = raw3270_wake_init; |
571 | rq->callback_data = &wq; | 569 | rq->callback_data = &raw3270_wait_queue; |
572 | spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags); | 570 | spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags); |
573 | rc = __raw3270_start(rp, view, rq); | 571 | rc = __raw3270_start(rp, view, rq); |
574 | spin_unlock_irqrestore(get_ccwdev_lock(view->dev->cdev), flags); | 572 | spin_unlock_irqrestore(get_ccwdev_lock(view->dev->cdev), flags); |
575 | if (rc) | 573 | if (rc) |
576 | return rc; | 574 | return rc; |
577 | /* Now wait for the completion. */ | 575 | /* Now wait for the completion. */ |
578 | rc = wait_event_interruptible(wq, raw3270_request_final(rq)); | 576 | rc = wait_event_interruptible(raw3270_wait_queue, |
577 | raw3270_request_final(rq)); | ||
579 | if (rc == -ERESTARTSYS) { /* Interrupted by a signal. */ | 578 | if (rc == -ERESTARTSYS) { /* Interrupted by a signal. */ |
580 | raw3270_halt_io(view->dev, rq); | 579 | raw3270_halt_io(view->dev, rq); |
581 | /* No wait for the halt to complete. */ | 580 | /* No wait for the halt to complete. */ |
582 | wait_event(wq, raw3270_request_final(rq)); | 581 | wait_event(raw3270_wait_queue, raw3270_request_final(rq)); |
583 | return -ERESTARTSYS; | 582 | return -ERESTARTSYS; |
584 | } | 583 | } |
585 | return rq->rc; | 584 | return rq->rc; |
diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index 9e784d5f7f57..ad05a87bc480 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c | |||
@@ -40,7 +40,7 @@ static void sclp_cpu_capability_notify(struct work_struct *work) | |||
40 | put_online_cpus(); | 40 | put_online_cpus(); |
41 | } | 41 | } |
42 | 42 | ||
43 | static void sclp_cpu_change_notify(struct work_struct *work) | 43 | static void __ref sclp_cpu_change_notify(struct work_struct *work) |
44 | { | 44 | { |
45 | smp_rescan_cpus(); | 45 | smp_rescan_cpus(); |
46 | } | 46 | } |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 35707c04e613..3e577f655b18 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; |
@@ -786,6 +773,7 @@ sclp_vt220_con_init(void) | |||
786 | { | 773 | { |
787 | int rc; | 774 | int rc; |
788 | 775 | ||
776 | INIT_LIST_HEAD(&sclp_vt220_register.list); | ||
789 | if (!CONSOLE_IS_SCLP) | 777 | if (!CONSOLE_IS_SCLP) |
790 | return 0; | 778 | return 0; |
791 | rc = __sclp_vt220_init(); | 779 | rc = __sclp_vt220_init(); |
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h index dddf8d62c153..d0d565a05dfe 100644 --- a/drivers/s390/char/tape.h +++ b/drivers/s390/char/tape.h | |||
@@ -231,6 +231,9 @@ struct tape_device { | |||
231 | /* Request queue. */ | 231 | /* Request queue. */ |
232 | struct list_head req_queue; | 232 | struct list_head req_queue; |
233 | 233 | ||
234 | /* Request wait queue. */ | ||
235 | wait_queue_head_t wait_queue; | ||
236 | |||
234 | /* Each tape device has (currently) two minor numbers. */ | 237 | /* Each tape device has (currently) two minor numbers. */ |
235 | int first_minor; | 238 | int first_minor; |
236 | 239 | ||
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 8246ef3ab095..42ce7915fc5d 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c | |||
@@ -1598,7 +1598,7 @@ tape_3590_setup_device(struct tape_device *device) | |||
1598 | rc = tape_3590_read_dev_chars(device, rdc_data); | 1598 | rc = tape_3590_read_dev_chars(device, rdc_data); |
1599 | if (rc) { | 1599 | if (rc) { |
1600 | DBF_LH(3, "Read device characteristics failed!\n"); | 1600 | DBF_LH(3, "Read device characteristics failed!\n"); |
1601 | goto fail_kmalloc; | 1601 | goto fail_rdc_data; |
1602 | } | 1602 | } |
1603 | rc = tape_std_assign(device); | 1603 | rc = tape_std_assign(device); |
1604 | if (rc) | 1604 | if (rc) |
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index ddc4a114e7f4..95da72bc17e8 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c | |||
@@ -179,11 +179,11 @@ tapeblock_requeue(struct work_struct *work) { | |||
179 | tapeblock_end_request(req, -EIO); | 179 | tapeblock_end_request(req, -EIO); |
180 | continue; | 180 | continue; |
181 | } | 181 | } |
182 | blkdev_dequeue_request(req); | ||
183 | nr_queued++; | ||
182 | spin_unlock_irq(&device->blk_data.request_queue_lock); | 184 | spin_unlock_irq(&device->blk_data.request_queue_lock); |
183 | rc = tapeblock_start_request(device, req); | 185 | rc = tapeblock_start_request(device, req); |
184 | spin_lock_irq(&device->blk_data.request_queue_lock); | 186 | spin_lock_irq(&device->blk_data.request_queue_lock); |
185 | blkdev_dequeue_request(req); | ||
186 | nr_queued++; | ||
187 | } | 187 | } |
188 | spin_unlock_irq(&device->blk_data.request_queue_lock); | 188 | spin_unlock_irq(&device->blk_data.request_queue_lock); |
189 | atomic_set(&device->blk_data.requeue_scheduled, 0); | 189 | atomic_set(&device->blk_data.requeue_scheduled, 0); |
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 76e44eb7c47f..c20e3c548343 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -449,6 +449,7 @@ tape_alloc_device(void) | |||
449 | INIT_LIST_HEAD(&device->req_queue); | 449 | INIT_LIST_HEAD(&device->req_queue); |
450 | INIT_LIST_HEAD(&device->node); | 450 | INIT_LIST_HEAD(&device->node); |
451 | init_waitqueue_head(&device->state_change_wq); | 451 | init_waitqueue_head(&device->state_change_wq); |
452 | init_waitqueue_head(&device->wait_queue); | ||
452 | device->tape_state = TS_INIT; | 453 | device->tape_state = TS_INIT; |
453 | device->medium_state = MS_UNKNOWN; | 454 | device->medium_state = MS_UNKNOWN; |
454 | *device->modeset_byte = 0; | 455 | *device->modeset_byte = 0; |
@@ -954,21 +955,19 @@ __tape_wake_up(struct tape_request *request, void *data) | |||
954 | int | 955 | int |
955 | tape_do_io(struct tape_device *device, struct tape_request *request) | 956 | tape_do_io(struct tape_device *device, struct tape_request *request) |
956 | { | 957 | { |
957 | wait_queue_head_t wq; | ||
958 | int rc; | 958 | int rc; |
959 | 959 | ||
960 | init_waitqueue_head(&wq); | ||
961 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 960 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
962 | /* Setup callback */ | 961 | /* Setup callback */ |
963 | request->callback = __tape_wake_up; | 962 | request->callback = __tape_wake_up; |
964 | request->callback_data = &wq; | 963 | request->callback_data = &device->wait_queue; |
965 | /* Add request to request queue and try to start it. */ | 964 | /* Add request to request queue and try to start it. */ |
966 | rc = __tape_start_request(device, request); | 965 | rc = __tape_start_request(device, request); |
967 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 966 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
968 | if (rc) | 967 | if (rc) |
969 | return rc; | 968 | return rc; |
970 | /* Request added to the queue. Wait for its completion. */ | 969 | /* Request added to the queue. Wait for its completion. */ |
971 | wait_event(wq, (request->callback == NULL)); | 970 | wait_event(device->wait_queue, (request->callback == NULL)); |
972 | /* Get rc from request */ | 971 | /* Get rc from request */ |
973 | return request->rc; | 972 | return request->rc; |
974 | } | 973 | } |
@@ -989,20 +988,19 @@ int | |||
989 | tape_do_io_interruptible(struct tape_device *device, | 988 | tape_do_io_interruptible(struct tape_device *device, |
990 | struct tape_request *request) | 989 | struct tape_request *request) |
991 | { | 990 | { |
992 | wait_queue_head_t wq; | ||
993 | int rc; | 991 | int rc; |
994 | 992 | ||
995 | init_waitqueue_head(&wq); | ||
996 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | 993 | spin_lock_irq(get_ccwdev_lock(device->cdev)); |
997 | /* Setup callback */ | 994 | /* Setup callback */ |
998 | request->callback = __tape_wake_up_interruptible; | 995 | request->callback = __tape_wake_up_interruptible; |
999 | request->callback_data = &wq; | 996 | request->callback_data = &device->wait_queue; |
1000 | rc = __tape_start_request(device, request); | 997 | rc = __tape_start_request(device, request); |
1001 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | 998 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); |
1002 | if (rc) | 999 | if (rc) |
1003 | return rc; | 1000 | return rc; |
1004 | /* Request added to the queue. Wait for its completion. */ | 1001 | /* Request added to the queue. Wait for its completion. */ |
1005 | rc = wait_event_interruptible(wq, (request->callback == NULL)); | 1002 | rc = wait_event_interruptible(device->wait_queue, |
1003 | (request->callback == NULL)); | ||
1006 | if (rc != -ERESTARTSYS) | 1004 | if (rc != -ERESTARTSYS) |
1007 | /* Request finished normally. */ | 1005 | /* Request finished normally. */ |
1008 | return request->rc; | 1006 | return request->rc; |
@@ -1015,7 +1013,7 @@ tape_do_io_interruptible(struct tape_device *device, | |||
1015 | /* Wait for the interrupt that acknowledges the halt. */ | 1013 | /* Wait for the interrupt that acknowledges the halt. */ |
1016 | do { | 1014 | do { |
1017 | rc = wait_event_interruptible( | 1015 | rc = wait_event_interruptible( |
1018 | wq, | 1016 | device->wait_queue, |
1019 | (request->callback == NULL) | 1017 | (request->callback == NULL) |
1020 | ); | 1018 | ); |
1021 | } while (rc == -ERESTARTSYS); | 1019 | } while (rc == -ERESTARTSYS); |