aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-22 19:12:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-22 19:12:24 -0400
commit94b5aff4c6f72fee6b0f49d49e4fa8b204e8ded9 (patch)
tree39197121b6ef8cddaa0f4057fe24b4ced58e8982 /drivers/s390
parent5d4e2d08e7fdf7339f84a1c670d296a77e02f881 (diff)
parent59bd234b72fc29887839d792b7d6c7e8d2a577a6 (diff)
Merge tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull TTY updates from Greg Kroah-Hartman: "Here's the big TTY/serial driver pull request for the 3.5-rc1 merge window. Nothing major in here, just lots of incremental changes from Alan and Jiri reworking some tty core things to behave better and to get a more solid grasp on some of the nasty tty locking issues. There are a few tty and serial driver updates in here as well. All of this has been in the linux-next releases for a while with no problems. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (115 commits) serial: bfin_uart: Make MMR access compatible with 32 bits bf609 style controller. serial: bfin_uart: RTS and CTS MMRs can be either 16-bit width or 32-bit width. serial: bfin_uart: narrow the reboot condition in DMA tx interrupt serial: bfin_uart: Adapt bf5xx serial driver to bf60x serial4 controller. Revert "serial_core: Update buffer overrun statistics." tty: hvc_xen: NULL dereference on allocation failure tty: Fix LED error return tty: Allow uart_register/unregister/register tty: move global ldisc idle waitqueue to the individual ldisc serial8250-em: Add DT support serial8250-em: clk_get() IS_ERR() error handling fix serial_core: Update buffer overrun statistics. tty: drop the pty lock during hangup cris: fix missing tty arg in wait_event_interruptible_tty call tty/amiserial: Add missing argument for tty_unlock() tty_lock: Localise the lock pty: Lock the devpts bits privately tty_lock: undo the old tty_lock use on the ctty serial8250-em: Emma Mobile UART driver V2 Add missing call to uart_update_timeout() ...
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/char/con3215.c142
-rw-r--r--drivers/s390/char/keyboard.c30
-rw-r--r--drivers/s390/char/keyboard.h14
-rw-r--r--drivers/s390/char/sclp_tty.c33
-rw-r--r--drivers/s390/char/sclp_vt220.c33
-rw-r--r--drivers/s390/char/tty3270.c121
6 files changed, 194 insertions, 179 deletions
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 4f9f1dcc1551..6c0116d48c74 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -20,6 +20,7 @@
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/reboot.h> 22#include <linux/reboot.h>
23#include <linux/serial.h> /* ASYNC_* flags */
23#include <linux/slab.h> 24#include <linux/slab.h>
24#include <asm/ccwdev.h> 25#include <asm/ccwdev.h>
25#include <asm/cio.h> 26#include <asm/cio.h>
@@ -44,14 +45,11 @@
44#define RAW3215_TIMEOUT HZ/10 /* time for delayed output */ 45#define RAW3215_TIMEOUT HZ/10 /* time for delayed output */
45 46
46#define RAW3215_FIXED 1 /* 3215 console device is not be freed */ 47#define RAW3215_FIXED 1 /* 3215 console device is not be freed */
47#define RAW3215_ACTIVE 2 /* set if the device is in use */
48#define RAW3215_WORKING 4 /* set if a request is being worked on */ 48#define RAW3215_WORKING 4 /* set if a request is being worked on */
49#define RAW3215_THROTTLED 8 /* set if reading is disabled */ 49#define RAW3215_THROTTLED 8 /* set if reading is disabled */
50#define RAW3215_STOPPED 16 /* set if writing is disabled */ 50#define RAW3215_STOPPED 16 /* set if writing is disabled */
51#define RAW3215_CLOSING 32 /* set while in close process */
52#define RAW3215_TIMER_RUNS 64 /* set if the output delay timer is on */ 51#define RAW3215_TIMER_RUNS 64 /* set if the output delay timer is on */
53#define RAW3215_FLUSHING 128 /* set to flush buffer (no delay) */ 52#define RAW3215_FLUSHING 128 /* set to flush buffer (no delay) */
54#define RAW3215_FROZEN 256 /* set if 3215 is frozen for suspend */
55 53
56#define TAB_STOP_SIZE 8 /* tab stop size */ 54#define TAB_STOP_SIZE 8 /* tab stop size */
57 55
@@ -76,6 +74,7 @@ struct raw3215_req {
76} __attribute__ ((aligned(8))); 74} __attribute__ ((aligned(8)));
77 75
78struct raw3215_info { 76struct raw3215_info {
77 struct tty_port port;
79 struct ccw_device *cdev; /* device for tty driver */ 78 struct ccw_device *cdev; /* device for tty driver */
80 spinlock_t *lock; /* pointer to irq lock */ 79 spinlock_t *lock; /* pointer to irq lock */
81 int flags; /* state flags */ 80 int flags; /* state flags */
@@ -84,7 +83,6 @@ struct raw3215_info {
84 int head; /* first free byte in output buffer */ 83 int head; /* first free byte in output buffer */
85 int count; /* number of bytes in output buffer */ 84 int count; /* number of bytes in output buffer */
86 int written; /* number of bytes in write requests */ 85 int written; /* number of bytes in write requests */
87 struct tty_struct *tty; /* pointer to tty structure if present */
88 struct raw3215_req *queued_read; /* pointer to queued read requests */ 86 struct raw3215_req *queued_read; /* pointer to queued read requests */
89 struct raw3215_req *queued_write;/* pointer to queued write requests */ 87 struct raw3215_req *queued_write;/* pointer to queued write requests */
90 struct tasklet_struct tlet; /* tasklet to invoke tty_wakeup */ 88 struct tasklet_struct tlet; /* tasklet to invoke tty_wakeup */
@@ -293,7 +291,7 @@ static void raw3215_timeout(unsigned long __data)
293 if (raw->flags & RAW3215_TIMER_RUNS) { 291 if (raw->flags & RAW3215_TIMER_RUNS) {
294 del_timer(&raw->timer); 292 del_timer(&raw->timer);
295 raw->flags &= ~RAW3215_TIMER_RUNS; 293 raw->flags &= ~RAW3215_TIMER_RUNS;
296 if (!(raw->flags & RAW3215_FROZEN)) { 294 if (!(raw->port.flags & ASYNC_SUSPENDED)) {
297 raw3215_mk_write_req(raw); 295 raw3215_mk_write_req(raw);
298 raw3215_start_io(raw); 296 raw3215_start_io(raw);
299 } 297 }
@@ -309,7 +307,8 @@ static void raw3215_timeout(unsigned long __data)
309 */ 307 */
310static inline void raw3215_try_io(struct raw3215_info *raw) 308static inline void raw3215_try_io(struct raw3215_info *raw)
311{ 309{
312 if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FROZEN)) 310 if (!(raw->port.flags & ASYNC_INITIALIZED) ||
311 (raw->port.flags & ASYNC_SUSPENDED))
313 return; 312 return;
314 if (raw->queued_read != NULL) 313 if (raw->queued_read != NULL)
315 raw3215_start_io(raw); 314 raw3215_start_io(raw);
@@ -324,10 +323,7 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
324 } 323 }
325 } else if (!(raw->flags & RAW3215_TIMER_RUNS)) { 324 } else if (!(raw->flags & RAW3215_TIMER_RUNS)) {
326 /* delay small writes */ 325 /* delay small writes */
327 init_timer(&raw->timer);
328 raw->timer.expires = RAW3215_TIMEOUT + jiffies; 326 raw->timer.expires = RAW3215_TIMEOUT + jiffies;
329 raw->timer.data = (unsigned long) raw;
330 raw->timer.function = raw3215_timeout;
331 add_timer(&raw->timer); 327 add_timer(&raw->timer);
332 raw->flags |= RAW3215_TIMER_RUNS; 328 raw->flags |= RAW3215_TIMER_RUNS;
333 } 329 }
@@ -340,17 +336,21 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
340static void raw3215_wakeup(unsigned long data) 336static void raw3215_wakeup(unsigned long data)
341{ 337{
342 struct raw3215_info *raw = (struct raw3215_info *) data; 338 struct raw3215_info *raw = (struct raw3215_info *) data;
343 tty_wakeup(raw->tty); 339 struct tty_struct *tty;
340
341 tty = tty_port_tty_get(&raw->port);
342 tty_wakeup(tty);
343 tty_kref_put(tty);
344} 344}
345 345
346/* 346/*
347 * Try to start the next IO and wake up processes waiting on the tty. 347 * Try to start the next IO and wake up processes waiting on the tty.
348 */ 348 */
349static void raw3215_next_io(struct raw3215_info *raw) 349static void raw3215_next_io(struct raw3215_info *raw, struct tty_struct *tty)
350{ 350{
351 raw3215_mk_write_req(raw); 351 raw3215_mk_write_req(raw);
352 raw3215_try_io(raw); 352 raw3215_try_io(raw);
353 if (raw->tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) 353 if (tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE)
354 tasklet_schedule(&raw->tlet); 354 tasklet_schedule(&raw->tlet);
355} 355}
356 356
@@ -368,10 +368,11 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
368 368
369 raw = dev_get_drvdata(&cdev->dev); 369 raw = dev_get_drvdata(&cdev->dev);
370 req = (struct raw3215_req *) intparm; 370 req = (struct raw3215_req *) intparm;
371 tty = tty_port_tty_get(&raw->port);
371 cstat = irb->scsw.cmd.cstat; 372 cstat = irb->scsw.cmd.cstat;
372 dstat = irb->scsw.cmd.dstat; 373 dstat = irb->scsw.cmd.dstat;
373 if (cstat != 0) 374 if (cstat != 0)
374 raw3215_next_io(raw); 375 raw3215_next_io(raw, tty);
375 if (dstat & 0x01) { /* we got a unit exception */ 376 if (dstat & 0x01) { /* we got a unit exception */
376 dstat &= ~0x01; /* we can ignore it */ 377 dstat &= ~0x01; /* we can ignore it */
377 } 378 }
@@ -381,13 +382,13 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
381 break; 382 break;
382 /* Attention interrupt, someone hit the enter key */ 383 /* Attention interrupt, someone hit the enter key */
383 raw3215_mk_read_req(raw); 384 raw3215_mk_read_req(raw);
384 raw3215_next_io(raw); 385 raw3215_next_io(raw, tty);
385 break; 386 break;
386 case 0x08: 387 case 0x08:
387 case 0x0C: 388 case 0x0C:
388 /* Channel end interrupt. */ 389 /* Channel end interrupt. */
389 if ((raw = req->info) == NULL) 390 if ((raw = req->info) == NULL)
390 return; /* That shouldn't happen ... */ 391 goto put_tty; /* That shouldn't happen ... */
391 if (req->type == RAW3215_READ) { 392 if (req->type == RAW3215_READ) {
392 /* store residual count, then wait for device end */ 393 /* store residual count, then wait for device end */
393 req->residual = irb->scsw.cmd.count; 394 req->residual = irb->scsw.cmd.count;
@@ -397,11 +398,10 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
397 case 0x04: 398 case 0x04:
398 /* Device end interrupt. */ 399 /* Device end interrupt. */
399 if ((raw = req->info) == NULL) 400 if ((raw = req->info) == NULL)
400 return; /* That shouldn't happen ... */ 401 goto put_tty; /* That shouldn't happen ... */
401 if (req->type == RAW3215_READ && raw->tty != NULL) { 402 if (req->type == RAW3215_READ && tty != NULL) {
402 unsigned int cchar; 403 unsigned int cchar;
403 404
404 tty = raw->tty;
405 count = 160 - req->residual; 405 count = 160 - req->residual;
406 EBCASC(raw->inbuf, count); 406 EBCASC(raw->inbuf, count);
407 cchar = ctrlchar_handle(raw->inbuf, count, tty); 407 cchar = ctrlchar_handle(raw->inbuf, count, tty);
@@ -411,7 +411,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
411 411
412 case CTRLCHAR_CTRL: 412 case CTRLCHAR_CTRL:
413 tty_insert_flip_char(tty, cchar, TTY_NORMAL); 413 tty_insert_flip_char(tty, cchar, TTY_NORMAL);
414 tty_flip_buffer_push(raw->tty); 414 tty_flip_buffer_push(tty);
415 break; 415 break;
416 416
417 case CTRLCHAR_NONE: 417 case CTRLCHAR_NONE:
@@ -424,7 +424,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
424 } else 424 } else
425 count -= 2; 425 count -= 2;
426 tty_insert_flip_string(tty, raw->inbuf, count); 426 tty_insert_flip_string(tty, raw->inbuf, count);
427 tty_flip_buffer_push(raw->tty); 427 tty_flip_buffer_push(tty);
428 break; 428 break;
429 } 429 }
430 } else if (req->type == RAW3215_WRITE) { 430 } else if (req->type == RAW3215_WRITE) {
@@ -439,7 +439,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
439 raw->queued_read == NULL) { 439 raw->queued_read == NULL) {
440 wake_up_interruptible(&raw->empty_wait); 440 wake_up_interruptible(&raw->empty_wait);
441 } 441 }
442 raw3215_next_io(raw); 442 raw3215_next_io(raw, tty);
443 break; 443 break;
444 default: 444 default:
445 /* Strange interrupt, I'll do my best to clean up */ 445 /* Strange interrupt, I'll do my best to clean up */
@@ -451,9 +451,10 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
451 raw->flags &= ~RAW3215_WORKING; 451 raw->flags &= ~RAW3215_WORKING;
452 raw3215_free_req(req); 452 raw3215_free_req(req);
453 } 453 }
454 raw3215_next_io(raw); 454 raw3215_next_io(raw, tty);
455 } 455 }
456 return; 456put_tty:
457 tty_kref_put(tty);
457} 458}
458 459
459/* 460/*
@@ -487,7 +488,7 @@ static void raw3215_make_room(struct raw3215_info *raw, unsigned int length)
487 /* While console is frozen for suspend we have no other 488 /* While console is frozen for suspend we have no other
488 * choice but to drop message from the buffer to make 489 * choice but to drop message from the buffer to make
489 * room for even more messages. */ 490 * room for even more messages. */
490 if (raw->flags & RAW3215_FROZEN) { 491 if (raw->port.flags & ASYNC_SUSPENDED) {
491 raw3215_drop_line(raw); 492 raw3215_drop_line(raw);
492 continue; 493 continue;
493 } 494 }
@@ -609,10 +610,10 @@ static int raw3215_startup(struct raw3215_info *raw)
609{ 610{
610 unsigned long flags; 611 unsigned long flags;
611 612
612 if (raw->flags & RAW3215_ACTIVE) 613 if (raw->port.flags & ASYNC_INITIALIZED)
613 return 0; 614 return 0;
614 raw->line_pos = 0; 615 raw->line_pos = 0;
615 raw->flags |= RAW3215_ACTIVE; 616 raw->port.flags |= ASYNC_INITIALIZED;
616 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); 617 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
617 raw3215_try_io(raw); 618 raw3215_try_io(raw);
618 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 619 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
@@ -628,14 +629,15 @@ static void raw3215_shutdown(struct raw3215_info *raw)
628 DECLARE_WAITQUEUE(wait, current); 629 DECLARE_WAITQUEUE(wait, current);
629 unsigned long flags; 630 unsigned long flags;
630 631
631 if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FIXED)) 632 if (!(raw->port.flags & ASYNC_INITIALIZED) ||
633 (raw->flags & RAW3215_FIXED))
632 return; 634 return;
633 /* Wait for outstanding requests, then free irq */ 635 /* Wait for outstanding requests, then free irq */
634 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); 636 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
635 if ((raw->flags & RAW3215_WORKING) || 637 if ((raw->flags & RAW3215_WORKING) ||
636 raw->queued_write != NULL || 638 raw->queued_write != NULL ||
637 raw->queued_read != NULL) { 639 raw->queued_read != NULL) {
638 raw->flags |= RAW3215_CLOSING; 640 raw->port.flags |= ASYNC_CLOSING;
639 add_wait_queue(&raw->empty_wait, &wait); 641 add_wait_queue(&raw->empty_wait, &wait);
640 set_current_state(TASK_INTERRUPTIBLE); 642 set_current_state(TASK_INTERRUPTIBLE);
641 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 643 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
@@ -643,11 +645,41 @@ static void raw3215_shutdown(struct raw3215_info *raw)
643 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); 645 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
644 remove_wait_queue(&raw->empty_wait, &wait); 646 remove_wait_queue(&raw->empty_wait, &wait);
645 set_current_state(TASK_RUNNING); 647 set_current_state(TASK_RUNNING);
646 raw->flags &= ~(RAW3215_ACTIVE | RAW3215_CLOSING); 648 raw->port.flags &= ~(ASYNC_INITIALIZED | ASYNC_CLOSING);
647 } 649 }
648 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 650 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
649} 651}
650 652
653static struct raw3215_info *raw3215_alloc_info(void)
654{
655 struct raw3215_info *info;
656
657 info = kzalloc(sizeof(struct raw3215_info), GFP_KERNEL | GFP_DMA);
658 if (!info)
659 return NULL;
660
661 info->buffer = kzalloc(RAW3215_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
662 info->inbuf = kzalloc(RAW3215_INBUF_SIZE, GFP_KERNEL | GFP_DMA);
663 if (!info->buffer || !info->inbuf) {
664 kfree(info);
665 return NULL;
666 }
667
668 setup_timer(&info->timer, raw3215_timeout, (unsigned long)info);
669 init_waitqueue_head(&info->empty_wait);
670 tasklet_init(&info->tlet, raw3215_wakeup, (unsigned long)info);
671 tty_port_init(&info->port);
672
673 return info;
674}
675
676static void raw3215_free_info(struct raw3215_info *raw)
677{
678 kfree(raw->inbuf);
679 kfree(raw->buffer);
680 kfree(raw);
681}
682
651static int raw3215_probe (struct ccw_device *cdev) 683static int raw3215_probe (struct ccw_device *cdev)
652{ 684{
653 struct raw3215_info *raw; 685 struct raw3215_info *raw;
@@ -656,11 +688,15 @@ static int raw3215_probe (struct ccw_device *cdev)
656 /* Console is special. */ 688 /* Console is special. */
657 if (raw3215[0] && (raw3215[0] == dev_get_drvdata(&cdev->dev))) 689 if (raw3215[0] && (raw3215[0] == dev_get_drvdata(&cdev->dev)))
658 return 0; 690 return 0;
659 raw = kmalloc(sizeof(struct raw3215_info) + 691
660 RAW3215_INBUF_SIZE, GFP_KERNEL|GFP_DMA); 692 raw = raw3215_alloc_info();
661 if (raw == NULL) 693 if (raw == NULL)
662 return -ENOMEM; 694 return -ENOMEM;
663 695
696 raw->cdev = cdev;
697 dev_set_drvdata(&cdev->dev, raw);
698 cdev->handler = raw3215_irq;
699
664 spin_lock(&raw3215_device_lock); 700 spin_lock(&raw3215_device_lock);
665 for (line = 0; line < NR_3215; line++) { 701 for (line = 0; line < NR_3215; line++) {
666 if (!raw3215[line]) { 702 if (!raw3215[line]) {
@@ -670,28 +706,10 @@ static int raw3215_probe (struct ccw_device *cdev)
670 } 706 }
671 spin_unlock(&raw3215_device_lock); 707 spin_unlock(&raw3215_device_lock);
672 if (line == NR_3215) { 708 if (line == NR_3215) {
673 kfree(raw); 709 raw3215_free_info(raw);
674 return -ENODEV; 710 return -ENODEV;
675 } 711 }
676 712
677 raw->cdev = cdev;
678 raw->inbuf = (char *) raw + sizeof(struct raw3215_info);
679 memset(raw, 0, sizeof(struct raw3215_info));
680 raw->buffer = kmalloc(RAW3215_BUFFER_SIZE,
681 GFP_KERNEL|GFP_DMA);
682 if (raw->buffer == NULL) {
683 spin_lock(&raw3215_device_lock);
684 raw3215[line] = NULL;
685 spin_unlock(&raw3215_device_lock);
686 kfree(raw);
687 return -ENOMEM;
688 }
689 init_waitqueue_head(&raw->empty_wait);
690 tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw);
691
692 dev_set_drvdata(&cdev->dev, raw);
693 cdev->handler = raw3215_irq;
694
695 return 0; 713 return 0;
696} 714}
697 715
@@ -703,8 +721,7 @@ static void raw3215_remove (struct ccw_device *cdev)
703 raw = dev_get_drvdata(&cdev->dev); 721 raw = dev_get_drvdata(&cdev->dev);
704 if (raw) { 722 if (raw) {
705 dev_set_drvdata(&cdev->dev, NULL); 723 dev_set_drvdata(&cdev->dev, NULL);
706 kfree(raw->buffer); 724 raw3215_free_info(raw);
707 kfree(raw);
708 } 725 }
709} 726}
710 727
@@ -741,7 +758,7 @@ static int raw3215_pm_stop(struct ccw_device *cdev)
741 raw = dev_get_drvdata(&cdev->dev); 758 raw = dev_get_drvdata(&cdev->dev);
742 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); 759 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
743 raw3215_make_room(raw, RAW3215_BUFFER_SIZE); 760 raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
744 raw->flags |= RAW3215_FROZEN; 761 raw->port.flags |= ASYNC_SUSPENDED;
745 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 762 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
746 return 0; 763 return 0;
747} 764}
@@ -754,7 +771,7 @@ static int raw3215_pm_start(struct ccw_device *cdev)
754 /* Allow I/O again and flush output buffer. */ 771 /* Allow I/O again and flush output buffer. */
755 raw = dev_get_drvdata(&cdev->dev); 772 raw = dev_get_drvdata(&cdev->dev);
756 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); 773 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
757 raw->flags &= ~RAW3215_FROZEN; 774 raw->port.flags &= ~ASYNC_SUSPENDED;
758 raw->flags |= RAW3215_FLUSHING; 775 raw->flags |= RAW3215_FLUSHING;
759 raw3215_try_io(raw); 776 raw3215_try_io(raw);
760 raw->flags &= ~RAW3215_FLUSHING; 777 raw->flags &= ~RAW3215_FLUSHING;
@@ -827,7 +844,7 @@ static void con3215_flush(void)
827 unsigned long flags; 844 unsigned long flags;
828 845
829 raw = raw3215[0]; /* console 3215 is the first one */ 846 raw = raw3215[0]; /* console 3215 is the first one */
830 if (raw->flags & RAW3215_FROZEN) 847 if (raw->port.flags & ASYNC_SUSPENDED)
831 /* The console is still frozen for suspend. */ 848 /* The console is still frozen for suspend. */
832 if (ccw_device_force_console()) 849 if (ccw_device_force_console())
833 /* Forcing didn't work, no panic message .. */ 850 /* Forcing didn't work, no panic message .. */
@@ -897,23 +914,16 @@ static int __init con3215_init(void)
897 if (IS_ERR(cdev)) 914 if (IS_ERR(cdev))
898 return -ENODEV; 915 return -ENODEV;
899 916
900 raw3215[0] = raw = (struct raw3215_info *) 917 raw3215[0] = raw = raw3215_alloc_info();
901 kzalloc(sizeof(struct raw3215_info), GFP_KERNEL | GFP_DMA);
902 raw->buffer = kzalloc(RAW3215_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
903 raw->inbuf = kzalloc(RAW3215_INBUF_SIZE, GFP_KERNEL | GFP_DMA);
904 raw->cdev = cdev; 918 raw->cdev = cdev;
905 dev_set_drvdata(&cdev->dev, raw); 919 dev_set_drvdata(&cdev->dev, raw);
906 cdev->handler = raw3215_irq; 920 cdev->handler = raw3215_irq;
907 921
908 raw->flags |= RAW3215_FIXED; 922 raw->flags |= RAW3215_FIXED;
909 init_waitqueue_head(&raw->empty_wait);
910 tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw);
911 923
912 /* Request the console irq */ 924 /* Request the console irq */
913 if (raw3215_startup(raw) != 0) { 925 if (raw3215_startup(raw) != 0) {
914 kfree(raw->inbuf); 926 raw3215_free_info(raw);
915 kfree(raw->buffer);
916 kfree(raw);
917 raw3215[0] = NULL; 927 raw3215[0] = NULL;
918 return -ENODEV; 928 return -ENODEV;
919 } 929 }
@@ -940,7 +950,7 @@ static int tty3215_open(struct tty_struct *tty, struct file * filp)
940 return -ENODEV; 950 return -ENODEV;
941 951
942 tty->driver_data = raw; 952 tty->driver_data = raw;
943 raw->tty = tty; 953 tty_port_tty_set(&raw->port, tty);
944 954
945 tty->low_latency = 0; /* don't use bottom half for pushing chars */ 955 tty->low_latency = 0; /* don't use bottom half for pushing chars */
946 /* 956 /*
@@ -971,7 +981,7 @@ static void tty3215_close(struct tty_struct *tty, struct file * filp)
971 raw3215_shutdown(raw); 981 raw3215_shutdown(raw);
972 tasklet_kill(&raw->tlet); 982 tasklet_kill(&raw->tlet);
973 tty->closing = 0; 983 tty->closing = 0;
974 raw->tty = NULL; 984 tty_port_tty_set(&raw->port, NULL);
975} 985}
976 986
977/* 987/*
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c
index 806588192483..7ef9cfdc17d8 100644
--- a/drivers/s390/char/keyboard.c
+++ b/drivers/s390/char/keyboard.c
@@ -199,7 +199,7 @@ handle_diacr(struct kbd_data *kbd, unsigned int ch)
199 if (ch == ' ' || ch == d) 199 if (ch == ' ' || ch == d)
200 return d; 200 return d;
201 201
202 kbd_put_queue(kbd->tty, d); 202 kbd_put_queue(kbd->port, d);
203 return ch; 203 return ch;
204} 204}
205 205
@@ -221,7 +221,7 @@ k_self(struct kbd_data *kbd, unsigned char value)
221{ 221{
222 if (kbd->diacr) 222 if (kbd->diacr)
223 value = handle_diacr(kbd, value); 223 value = handle_diacr(kbd, value);
224 kbd_put_queue(kbd->tty, value); 224 kbd_put_queue(kbd->port, value);
225} 225}
226 226
227/* 227/*
@@ -239,7 +239,7 @@ static void
239k_fn(struct kbd_data *kbd, unsigned char value) 239k_fn(struct kbd_data *kbd, unsigned char value)
240{ 240{
241 if (kbd->func_table[value]) 241 if (kbd->func_table[value])
242 kbd_puts_queue(kbd->tty, kbd->func_table[value]); 242 kbd_puts_queue(kbd->port, kbd->func_table[value]);
243} 243}
244 244
245static void 245static void
@@ -257,20 +257,20 @@ k_spec(struct kbd_data *kbd, unsigned char value)
257 * but we need only 16 bits here 257 * but we need only 16 bits here
258 */ 258 */
259static void 259static void
260to_utf8(struct tty_struct *tty, ushort c) 260to_utf8(struct tty_port *port, ushort c)
261{ 261{
262 if (c < 0x80) 262 if (c < 0x80)
263 /* 0******* */ 263 /* 0******* */
264 kbd_put_queue(tty, c); 264 kbd_put_queue(port, c);
265 else if (c < 0x800) { 265 else if (c < 0x800) {
266 /* 110***** 10****** */ 266 /* 110***** 10****** */
267 kbd_put_queue(tty, 0xc0 | (c >> 6)); 267 kbd_put_queue(port, 0xc0 | (c >> 6));
268 kbd_put_queue(tty, 0x80 | (c & 0x3f)); 268 kbd_put_queue(port, 0x80 | (c & 0x3f));
269 } else { 269 } else {
270 /* 1110**** 10****** 10****** */ 270 /* 1110**** 10****** 10****** */
271 kbd_put_queue(tty, 0xe0 | (c >> 12)); 271 kbd_put_queue(port, 0xe0 | (c >> 12));
272 kbd_put_queue(tty, 0x80 | ((c >> 6) & 0x3f)); 272 kbd_put_queue(port, 0x80 | ((c >> 6) & 0x3f));
273 kbd_put_queue(tty, 0x80 | (c & 0x3f)); 273 kbd_put_queue(port, 0x80 | (c & 0x3f));
274 } 274 }
275} 275}
276 276
@@ -283,7 +283,7 @@ kbd_keycode(struct kbd_data *kbd, unsigned int keycode)
283 unsigned short keysym; 283 unsigned short keysym;
284 unsigned char type, value; 284 unsigned char type, value;
285 285
286 if (!kbd || !kbd->tty) 286 if (!kbd)
287 return; 287 return;
288 288
289 if (keycode >= 384) 289 if (keycode >= 384)
@@ -323,7 +323,7 @@ kbd_keycode(struct kbd_data *kbd, unsigned int keycode)
323#endif 323#endif
324 (*k_handler[type])(kbd, value); 324 (*k_handler[type])(kbd, value);
325 } else 325 } else
326 to_utf8(kbd->tty, keysym); 326 to_utf8(kbd->port, keysym);
327} 327}
328 328
329/* 329/*
@@ -457,6 +457,7 @@ do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs,
457 457
458int kbd_ioctl(struct kbd_data *kbd, unsigned int cmd, unsigned long arg) 458int kbd_ioctl(struct kbd_data *kbd, unsigned int cmd, unsigned long arg)
459{ 459{
460 struct tty_struct *tty;
460 void __user *argp; 461 void __user *argp;
461 unsigned int ct; 462 unsigned int ct;
462 int perm; 463 int perm;
@@ -467,7 +468,10 @@ int kbd_ioctl(struct kbd_data *kbd, unsigned int cmd, unsigned long arg)
467 * To have permissions to do most of the vt ioctls, we either have 468 * To have permissions to do most of the vt ioctls, we either have
468 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG. 469 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
469 */ 470 */
470 perm = current->signal->tty == kbd->tty || capable(CAP_SYS_TTY_CONFIG); 471 tty = tty_port_tty_get(kbd->port);
472 /* FIXME this test is pretty racy */
473 perm = current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG);
474 tty_kref_put(tty);
471 switch (cmd) { 475 switch (cmd) {
472 case KDGKBTYPE: 476 case KDGKBTYPE:
473 return put_user(KB_101, (char __user *)argp); 477 return put_user(KB_101, (char __user *)argp);
diff --git a/drivers/s390/char/keyboard.h b/drivers/s390/char/keyboard.h
index 7e736aaeae6e..f682f4e49680 100644
--- a/drivers/s390/char/keyboard.h
+++ b/drivers/s390/char/keyboard.h
@@ -21,7 +21,7 @@ typedef void (fn_handler_fn)(struct kbd_data *);
21 */ 21 */
22 22
23struct kbd_data { 23struct kbd_data {
24 struct tty_struct *tty; 24 struct tty_port *port;
25 unsigned short **key_maps; 25 unsigned short **key_maps;
26 char **func_table; 26 char **func_table;
27 fn_handler_fn **fn_handler; 27 fn_handler_fn **fn_handler;
@@ -42,16 +42,24 @@ int kbd_ioctl(struct kbd_data *, unsigned int, unsigned long);
42 * Helper Functions. 42 * Helper Functions.
43 */ 43 */
44static inline void 44static inline void
45kbd_put_queue(struct tty_struct *tty, int ch) 45kbd_put_queue(struct tty_port *port, int ch)
46{ 46{
47 struct tty_struct *tty = tty_port_tty_get(port);
48 if (!tty)
49 return;
47 tty_insert_flip_char(tty, ch, 0); 50 tty_insert_flip_char(tty, ch, 0);
48 tty_schedule_flip(tty); 51 tty_schedule_flip(tty);
52 tty_kref_put(tty);
49} 53}
50 54
51static inline void 55static inline void
52kbd_puts_queue(struct tty_struct *tty, char *cp) 56kbd_puts_queue(struct tty_port *port, char *cp)
53{ 57{
58 struct tty_struct *tty = tty_port_tty_get(port);
59 if (!tty)
60 return;
54 while (*cp) 61 while (*cp)
55 tty_insert_flip_char(tty, *cp++, 0); 62 tty_insert_flip_char(tty, *cp++, 0);
56 tty_schedule_flip(tty); 63 tty_schedule_flip(tty);
64 tty_kref_put(tty);
57} 65}
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c
index 40a9d69c898e..e66a75b3822c 100644
--- a/drivers/s390/char/sclp_tty.c
+++ b/drivers/s390/char/sclp_tty.c
@@ -48,7 +48,7 @@ static struct sclp_buffer *sclp_ttybuf;
48/* Timer for delayed output of console messages. */ 48/* Timer for delayed output of console messages. */
49static struct timer_list sclp_tty_timer; 49static struct timer_list sclp_tty_timer;
50 50
51static struct tty_struct *sclp_tty; 51static struct tty_port sclp_port;
52static unsigned char sclp_tty_chars[SCLP_TTY_BUF_SIZE]; 52static unsigned char sclp_tty_chars[SCLP_TTY_BUF_SIZE];
53static unsigned short int sclp_tty_chars_count; 53static unsigned short int sclp_tty_chars_count;
54 54
@@ -64,7 +64,7 @@ static int sclp_tty_columns = 80;
64static int 64static int
65sclp_tty_open(struct tty_struct *tty, struct file *filp) 65sclp_tty_open(struct tty_struct *tty, struct file *filp)
66{ 66{
67 sclp_tty = tty; 67 tty_port_tty_set(&sclp_port, tty);
68 tty->driver_data = NULL; 68 tty->driver_data = NULL;
69 tty->low_latency = 0; 69 tty->low_latency = 0;
70 return 0; 70 return 0;
@@ -76,7 +76,7 @@ sclp_tty_close(struct tty_struct *tty, struct file *filp)
76{ 76{
77 if (tty->count > 1) 77 if (tty->count > 1)
78 return; 78 return;
79 sclp_tty = NULL; 79 tty_port_tty_set(&sclp_port, NULL);
80} 80}
81 81
82/* 82/*
@@ -108,6 +108,7 @@ sclp_tty_write_room (struct tty_struct *tty)
108static void 108static void
109sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc) 109sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc)
110{ 110{
111 struct tty_struct *tty;
111 unsigned long flags; 112 unsigned long flags;
112 void *page; 113 void *page;
113 114
@@ -126,8 +127,10 @@ sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc)
126 spin_unlock_irqrestore(&sclp_tty_lock, flags); 127 spin_unlock_irqrestore(&sclp_tty_lock, flags);
127 } while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback)); 128 } while (buffer && sclp_emit_buffer(buffer, sclp_ttybuf_callback));
128 /* check if the tty needs a wake up call */ 129 /* check if the tty needs a wake up call */
129 if (sclp_tty != NULL) { 130 tty = tty_port_tty_get(&sclp_port);
130 tty_wakeup(sclp_tty); 131 if (tty != NULL) {
132 tty_wakeup(tty);
133 tty_kref_put(tty);
131 } 134 }
132} 135}
133 136
@@ -326,21 +329,22 @@ sclp_tty_flush_buffer(struct tty_struct *tty)
326static void 329static void
327sclp_tty_input(unsigned char* buf, unsigned int count) 330sclp_tty_input(unsigned char* buf, unsigned int count)
328{ 331{
332 struct tty_struct *tty = tty_port_tty_get(&sclp_port);
329 unsigned int cchar; 333 unsigned int cchar;
330 334
331 /* 335 /*
332 * If this tty driver is currently closed 336 * If this tty driver is currently closed
333 * then throw the received input away. 337 * then throw the received input away.
334 */ 338 */
335 if (sclp_tty == NULL) 339 if (tty == NULL)
336 return; 340 return;
337 cchar = ctrlchar_handle(buf, count, sclp_tty); 341 cchar = ctrlchar_handle(buf, count, tty);
338 switch (cchar & CTRLCHAR_MASK) { 342 switch (cchar & CTRLCHAR_MASK) {
339 case CTRLCHAR_SYSRQ: 343 case CTRLCHAR_SYSRQ:
340 break; 344 break;
341 case CTRLCHAR_CTRL: 345 case CTRLCHAR_CTRL:
342 tty_insert_flip_char(sclp_tty, cchar, TTY_NORMAL); 346 tty_insert_flip_char(tty, cchar, TTY_NORMAL);
343 tty_flip_buffer_push(sclp_tty); 347 tty_flip_buffer_push(tty);
344 break; 348 break;
345 case CTRLCHAR_NONE: 349 case CTRLCHAR_NONE:
346 /* send (normal) input to line discipline */ 350 /* send (normal) input to line discipline */
@@ -348,13 +352,14 @@ sclp_tty_input(unsigned char* buf, unsigned int count)
348 (strncmp((const char *) buf + count - 2, "^n", 2) && 352 (strncmp((const char *) buf + count - 2, "^n", 2) &&
349 strncmp((const char *) buf + count - 2, "\252n", 2))) { 353 strncmp((const char *) buf + count - 2, "\252n", 2))) {
350 /* add the auto \n */ 354 /* add the auto \n */
351 tty_insert_flip_string(sclp_tty, buf, count); 355 tty_insert_flip_string(tty, buf, count);
352 tty_insert_flip_char(sclp_tty, '\n', TTY_NORMAL); 356 tty_insert_flip_char(tty, '\n', TTY_NORMAL);
353 } else 357 } else
354 tty_insert_flip_string(sclp_tty, buf, count - 2); 358 tty_insert_flip_string(tty, buf, count - 2);
355 tty_flip_buffer_push(sclp_tty); 359 tty_flip_buffer_push(tty);
356 break; 360 break;
357 } 361 }
362 tty_kref_put(tty);
358} 363}
359 364
360/* 365/*
@@ -543,7 +548,7 @@ sclp_tty_init(void)
543 sclp_tty_tolower = 1; 548 sclp_tty_tolower = 1;
544 } 549 }
545 sclp_tty_chars_count = 0; 550 sclp_tty_chars_count = 0;
546 sclp_tty = NULL; 551 tty_port_init(&sclp_port);
547 552
548 rc = sclp_register(&sclp_input_event); 553 rc = sclp_register(&sclp_input_event);
549 if (rc) { 554 if (rc) {
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index b635472ae660..edfc0fd73dc6 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -34,7 +34,6 @@
34#define SCLP_VT220_DEVICE_NAME "ttysclp" 34#define SCLP_VT220_DEVICE_NAME "ttysclp"
35#define SCLP_VT220_CONSOLE_NAME "ttyS" 35#define SCLP_VT220_CONSOLE_NAME "ttyS"
36#define SCLP_VT220_CONSOLE_INDEX 1 /* console=ttyS1 */ 36#define SCLP_VT220_CONSOLE_INDEX 1 /* console=ttyS1 */
37#define SCLP_VT220_BUF_SIZE 80
38 37
39/* Representation of a single write request */ 38/* Representation of a single write request */
40struct sclp_vt220_request { 39struct sclp_vt220_request {
@@ -56,8 +55,7 @@ struct sclp_vt220_sccb {
56/* Structures and data needed to register tty driver */ 55/* Structures and data needed to register tty driver */
57static struct tty_driver *sclp_vt220_driver; 56static struct tty_driver *sclp_vt220_driver;
58 57
59/* The tty_struct that the kernel associated with us */ 58static struct tty_port sclp_vt220_port;
60static struct tty_struct *sclp_vt220_tty;
61 59
62/* Lock to protect internal data from concurrent access */ 60/* Lock to protect internal data from concurrent access */
63static spinlock_t sclp_vt220_lock; 61static spinlock_t sclp_vt220_lock;
@@ -116,6 +114,7 @@ static struct sclp_register sclp_vt220_register = {
116static void 114static void
117sclp_vt220_process_queue(struct sclp_vt220_request *request) 115sclp_vt220_process_queue(struct sclp_vt220_request *request)
118{ 116{
117 struct tty_struct *tty;
119 unsigned long flags; 118 unsigned long flags;
120 void *page; 119 void *page;
121 120
@@ -141,8 +140,10 @@ sclp_vt220_process_queue(struct sclp_vt220_request *request)
141 if (request == NULL && sclp_vt220_flush_later) 140 if (request == NULL && sclp_vt220_flush_later)
142 sclp_vt220_emit_current(); 141 sclp_vt220_emit_current();
143 /* Check if the tty needs a wake up call */ 142 /* Check if the tty needs a wake up call */
144 if (sclp_vt220_tty != NULL) { 143 tty = tty_port_tty_get(&sclp_vt220_port);
145 tty_wakeup(sclp_vt220_tty); 144 if (tty) {
145 tty_wakeup(tty);
146 tty_kref_put(tty);
146 } 147 }
147} 148}
148 149
@@ -460,11 +461,12 @@ sclp_vt220_write(struct tty_struct *tty, const unsigned char *buf, int count)
460static void 461static void
461sclp_vt220_receiver_fn(struct evbuf_header *evbuf) 462sclp_vt220_receiver_fn(struct evbuf_header *evbuf)
462{ 463{
464 struct tty_struct *tty = tty_port_tty_get(&sclp_vt220_port);
463 char *buffer; 465 char *buffer;
464 unsigned int count; 466 unsigned int count;
465 467
466 /* Ignore input if device is not open */ 468 /* Ignore input if device is not open */
467 if (sclp_vt220_tty == NULL) 469 if (tty == NULL)
468 return; 470 return;
469 471
470 buffer = (char *) ((addr_t) evbuf + sizeof(struct evbuf_header)); 472 buffer = (char *) ((addr_t) evbuf + sizeof(struct evbuf_header));
@@ -478,10 +480,11 @@ sclp_vt220_receiver_fn(struct evbuf_header *evbuf)
478 /* Send input to line discipline */ 480 /* Send input to line discipline */
479 buffer++; 481 buffer++;
480 count--; 482 count--;
481 tty_insert_flip_string(sclp_vt220_tty, buffer, count); 483 tty_insert_flip_string(tty, buffer, count);
482 tty_flip_buffer_push(sclp_vt220_tty); 484 tty_flip_buffer_push(tty);
483 break; 485 break;
484 } 486 }
487 tty_kref_put(tty);
485} 488}
486 489
487/* 490/*
@@ -491,10 +494,7 @@ static int
491sclp_vt220_open(struct tty_struct *tty, struct file *filp) 494sclp_vt220_open(struct tty_struct *tty, struct file *filp)
492{ 495{
493 if (tty->count == 1) { 496 if (tty->count == 1) {
494 sclp_vt220_tty = tty; 497 tty_port_tty_set(&sclp_vt220_port, tty);
495 tty->driver_data = kmalloc(SCLP_VT220_BUF_SIZE, GFP_KERNEL);
496 if (tty->driver_data == NULL)
497 return -ENOMEM;
498 tty->low_latency = 0; 498 tty->low_latency = 0;
499 if (!tty->winsize.ws_row && !tty->winsize.ws_col) { 499 if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
500 tty->winsize.ws_row = 24; 500 tty->winsize.ws_row = 24;
@@ -510,11 +510,8 @@ sclp_vt220_open(struct tty_struct *tty, struct file *filp)
510static void 510static void
511sclp_vt220_close(struct tty_struct *tty, struct file *filp) 511sclp_vt220_close(struct tty_struct *tty, struct file *filp)
512{ 512{
513 if (tty->count == 1) { 513 if (tty->count == 1)
514 sclp_vt220_tty = NULL; 514 tty_port_tty_set(&sclp_vt220_port, NULL);
515 kfree(tty->driver_data);
516 tty->driver_data = NULL;
517 }
518} 515}
519 516
520/* 517/*
@@ -635,9 +632,9 @@ static int __init __sclp_vt220_init(int num_pages)
635 INIT_LIST_HEAD(&sclp_vt220_empty); 632 INIT_LIST_HEAD(&sclp_vt220_empty);
636 INIT_LIST_HEAD(&sclp_vt220_outqueue); 633 INIT_LIST_HEAD(&sclp_vt220_outqueue);
637 init_timer(&sclp_vt220_timer); 634 init_timer(&sclp_vt220_timer);
635 tty_port_init(&sclp_vt220_port);
638 sclp_vt220_current_request = NULL; 636 sclp_vt220_current_request = NULL;
639 sclp_vt220_buffered_chars = 0; 637 sclp_vt220_buffered_chars = 0;
640 sclp_vt220_tty = NULL;
641 sclp_vt220_flush_later = 0; 638 sclp_vt220_flush_later = 0;
642 639
643 /* Allocate pages for output buffering */ 640 /* Allocate pages for output buffering */
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index b43445a55cb6..10ec690197cb 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -61,7 +61,7 @@ struct tty3270_line {
61 */ 61 */
62struct tty3270 { 62struct tty3270 {
63 struct raw3270_view view; 63 struct raw3270_view view;
64 struct tty_struct *tty; /* Pointer to tty structure */ 64 struct tty_port port;
65 void **freemem_pages; /* Array of pages used for freemem. */ 65 void **freemem_pages; /* Array of pages used for freemem. */
66 struct list_head freemem; /* List of free memory for strings. */ 66 struct list_head freemem; /* List of free memory for strings. */
67 67
@@ -324,9 +324,8 @@ tty3270_blank_line(struct tty3270 *tp)
324static void 324static void
325tty3270_write_callback(struct raw3270_request *rq, void *data) 325tty3270_write_callback(struct raw3270_request *rq, void *data)
326{ 326{
327 struct tty3270 *tp; 327 struct tty3270 *tp = container_of(rq->view, struct tty3270, view);
328 328
329 tp = (struct tty3270 *) rq->view;
330 if (rq->rc != 0) { 329 if (rq->rc != 0) {
331 /* Write wasn't successful. Refresh all. */ 330 /* Write wasn't successful. Refresh all. */
332 tp->update_flags = TTY_UPDATE_ALL; 331 tp->update_flags = TTY_UPDATE_ALL;
@@ -450,10 +449,9 @@ tty3270_rcl_add(struct tty3270 *tp, char *input, int len)
450static void 449static void
451tty3270_rcl_backward(struct kbd_data *kbd) 450tty3270_rcl_backward(struct kbd_data *kbd)
452{ 451{
453 struct tty3270 *tp; 452 struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
454 struct string *s; 453 struct string *s;
455 454
456 tp = kbd->tty->driver_data;
457 spin_lock_bh(&tp->view.lock); 455 spin_lock_bh(&tp->view.lock);
458 if (tp->inattr == TF_INPUT) { 456 if (tp->inattr == TF_INPUT) {
459 if (tp->rcl_walk && tp->rcl_walk->prev != &tp->rcl_lines) 457 if (tp->rcl_walk && tp->rcl_walk->prev != &tp->rcl_lines)
@@ -478,9 +476,8 @@ tty3270_rcl_backward(struct kbd_data *kbd)
478static void 476static void
479tty3270_exit_tty(struct kbd_data *kbd) 477tty3270_exit_tty(struct kbd_data *kbd)
480{ 478{
481 struct tty3270 *tp; 479 struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
482 480
483 tp = kbd->tty->driver_data;
484 raw3270_deactivate_view(&tp->view); 481 raw3270_deactivate_view(&tp->view);
485} 482}
486 483
@@ -490,10 +487,9 @@ tty3270_exit_tty(struct kbd_data *kbd)
490static void 487static void
491tty3270_scroll_forward(struct kbd_data *kbd) 488tty3270_scroll_forward(struct kbd_data *kbd)
492{ 489{
493 struct tty3270 *tp; 490 struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
494 int nr_up; 491 int nr_up;
495 492
496 tp = kbd->tty->driver_data;
497 spin_lock_bh(&tp->view.lock); 493 spin_lock_bh(&tp->view.lock);
498 nr_up = tp->nr_up - tp->view.rows + 2; 494 nr_up = tp->nr_up - tp->view.rows + 2;
499 if (nr_up < 0) 495 if (nr_up < 0)
@@ -513,10 +509,9 @@ tty3270_scroll_forward(struct kbd_data *kbd)
513static void 509static void
514tty3270_scroll_backward(struct kbd_data *kbd) 510tty3270_scroll_backward(struct kbd_data *kbd)
515{ 511{
516 struct tty3270 *tp; 512 struct tty3270 *tp = container_of(kbd->port, struct tty3270, port);
517 int nr_up; 513 int nr_up;
518 514
519 tp = kbd->tty->driver_data;
520 spin_lock_bh(&tp->view.lock); 515 spin_lock_bh(&tp->view.lock);
521 nr_up = tp->nr_up + tp->view.rows - 2; 516 nr_up = tp->nr_up + tp->view.rows - 2;
522 if (nr_up + tp->view.rows - 2 > tp->nr_lines) 517 if (nr_up + tp->view.rows - 2 > tp->nr_lines)
@@ -537,11 +532,10 @@ static void
537tty3270_read_tasklet(struct raw3270_request *rrq) 532tty3270_read_tasklet(struct raw3270_request *rrq)
538{ 533{
539 static char kreset_data = TW_KR; 534 static char kreset_data = TW_KR;
540 struct tty3270 *tp; 535 struct tty3270 *tp = container_of(rrq->view, struct tty3270, view);
541 char *input; 536 char *input;
542 int len; 537 int len;
543 538
544 tp = (struct tty3270 *) rrq->view;
545 spin_lock_bh(&tp->view.lock); 539 spin_lock_bh(&tp->view.lock);
546 /* 540 /*
547 * Two AID keys are special: For 0x7d (enter) the input line 541 * Two AID keys are special: For 0x7d (enter) the input line
@@ -577,13 +571,10 @@ tty3270_read_tasklet(struct raw3270_request *rrq)
577 raw3270_request_add_data(tp->kreset, &kreset_data, 1); 571 raw3270_request_add_data(tp->kreset, &kreset_data, 1);
578 raw3270_start(&tp->view, tp->kreset); 572 raw3270_start(&tp->view, tp->kreset);
579 573
580 /* Emit input string. */ 574 while (len-- > 0)
581 if (tp->tty) { 575 kbd_keycode(tp->kbd, *input++);
582 while (len-- > 0) 576 /* Emit keycode for AID byte. */
583 kbd_keycode(tp->kbd, *input++); 577 kbd_keycode(tp->kbd, 256 + tp->input->string[0]);
584 /* Emit keycode for AID byte. */
585 kbd_keycode(tp->kbd, 256 + tp->input->string[0]);
586 }
587 578
588 raw3270_request_reset(rrq); 579 raw3270_request_reset(rrq);
589 xchg(&tp->read, rrq); 580 xchg(&tp->read, rrq);
@@ -596,9 +587,10 @@ tty3270_read_tasklet(struct raw3270_request *rrq)
596static void 587static void
597tty3270_read_callback(struct raw3270_request *rq, void *data) 588tty3270_read_callback(struct raw3270_request *rq, void *data)
598{ 589{
590 struct tty3270 *tp = container_of(rq->view, struct tty3270, view);
599 raw3270_get_view(rq->view); 591 raw3270_get_view(rq->view);
600 /* Schedule tasklet to pass input to tty. */ 592 /* Schedule tasklet to pass input to tty. */
601 tasklet_schedule(&((struct tty3270 *) rq->view)->readlet); 593 tasklet_schedule(&tp->readlet);
602} 594}
603 595
604/* 596/*
@@ -635,9 +627,8 @@ tty3270_issue_read(struct tty3270 *tp, int lock)
635static int 627static int
636tty3270_activate(struct raw3270_view *view) 628tty3270_activate(struct raw3270_view *view)
637{ 629{
638 struct tty3270 *tp; 630 struct tty3270 *tp = container_of(view, struct tty3270, view);
639 631
640 tp = (struct tty3270 *) view;
641 tp->update_flags = TTY_UPDATE_ALL; 632 tp->update_flags = TTY_UPDATE_ALL;
642 tty3270_set_timer(tp, 1); 633 tty3270_set_timer(tp, 1);
643 return 0; 634 return 0;
@@ -646,9 +637,8 @@ tty3270_activate(struct raw3270_view *view)
646static void 637static void
647tty3270_deactivate(struct raw3270_view *view) 638tty3270_deactivate(struct raw3270_view *view)
648{ 639{
649 struct tty3270 *tp; 640 struct tty3270 *tp = container_of(view, struct tty3270, view);
650 641
651 tp = (struct tty3270 *) view;
652 del_timer(&tp->timer); 642 del_timer(&tp->timer);
653} 643}
654 644
@@ -690,6 +680,17 @@ tty3270_alloc_view(void)
690 if (!tp->freemem_pages) 680 if (!tp->freemem_pages)
691 goto out_tp; 681 goto out_tp;
692 INIT_LIST_HEAD(&tp->freemem); 682 INIT_LIST_HEAD(&tp->freemem);
683 INIT_LIST_HEAD(&tp->lines);
684 INIT_LIST_HEAD(&tp->update);
685 INIT_LIST_HEAD(&tp->rcl_lines);
686 tp->rcl_max = 20;
687 tty_port_init(&tp->port);
688 setup_timer(&tp->timer, (void (*)(unsigned long)) tty3270_update,
689 (unsigned long) tp);
690 tasklet_init(&tp->readlet,
691 (void (*)(unsigned long)) tty3270_read_tasklet,
692 (unsigned long) tp->read);
693
693 for (pages = 0; pages < TTY3270_STRING_PAGES; pages++) { 694 for (pages = 0; pages < TTY3270_STRING_PAGES; pages++) {
694 tp->freemem_pages[pages] = (void *) 695 tp->freemem_pages[pages] = (void *)
695 __get_free_pages(GFP_KERNEL|GFP_DMA, 0); 696 __get_free_pages(GFP_KERNEL|GFP_DMA, 0);
@@ -794,16 +795,15 @@ tty3270_free_screen(struct tty3270 *tp)
794static void 795static void
795tty3270_release(struct raw3270_view *view) 796tty3270_release(struct raw3270_view *view)
796{ 797{
797 struct tty3270 *tp; 798 struct tty3270 *tp = container_of(view, struct tty3270, view);
798 struct tty_struct *tty; 799 struct tty_struct *tty = tty_port_tty_get(&tp->port);
799 800
800 tp = (struct tty3270 *) view;
801 tty = tp->tty;
802 if (tty) { 801 if (tty) {
803 tty->driver_data = NULL; 802 tty->driver_data = NULL;
804 tp->tty = tp->kbd->tty = NULL; 803 tty_port_tty_set(&tp->port, NULL);
805 tty_hangup(tty); 804 tty_hangup(tty);
806 raw3270_put_view(&tp->view); 805 raw3270_put_view(&tp->view);
806 tty_kref_put(tty);
807 } 807 }
808} 808}
809 809
@@ -813,8 +813,9 @@ tty3270_release(struct raw3270_view *view)
813static void 813static void
814tty3270_free(struct raw3270_view *view) 814tty3270_free(struct raw3270_view *view)
815{ 815{
816 tty3270_free_screen((struct tty3270 *) view); 816 struct tty3270 *tp = container_of(view, struct tty3270, view);
817 tty3270_free_view((struct tty3270 *) view); 817 tty3270_free_screen(tp);
818 tty3270_free_view(tp);
818} 819}
819 820
820/* 821/*
@@ -823,14 +824,13 @@ tty3270_free(struct raw3270_view *view)
823static void 824static void
824tty3270_del_views(void) 825tty3270_del_views(void)
825{ 826{
826 struct tty3270 *tp;
827 int i; 827 int i;
828 828
829 for (i = 0; i < tty3270_max_index; i++) { 829 for (i = 0; i < tty3270_max_index; i++) {
830 tp = (struct tty3270 *) 830 struct raw3270_view *view =
831 raw3270_find_view(&tty3270_fn, i + RAW3270_FIRSTMINOR); 831 raw3270_find_view(&tty3270_fn, i + RAW3270_FIRSTMINOR);
832 if (!IS_ERR(tp)) 832 if (!IS_ERR(view))
833 raw3270_del_view(&tp->view); 833 raw3270_del_view(view);
834 } 834 }
835} 835}
836 836
@@ -848,22 +848,23 @@ static struct raw3270_fn tty3270_fn = {
848static int 848static int
849tty3270_open(struct tty_struct *tty, struct file * filp) 849tty3270_open(struct tty_struct *tty, struct file * filp)
850{ 850{
851 struct raw3270_view *view;
851 struct tty3270 *tp; 852 struct tty3270 *tp;
852 int i, rc; 853 int i, rc;
853 854
854 if (tty->count > 1) 855 if (tty->count > 1)
855 return 0; 856 return 0;
856 /* Check if the tty3270 is already there. */ 857 /* Check if the tty3270 is already there. */
857 tp = (struct tty3270 *) 858 view = raw3270_find_view(&tty3270_fn,
858 raw3270_find_view(&tty3270_fn,
859 tty->index + RAW3270_FIRSTMINOR); 859 tty->index + RAW3270_FIRSTMINOR);
860 if (!IS_ERR(tp)) { 860 if (!IS_ERR(view)) {
861 tp = container_of(view, struct tty3270, view);
861 tty->driver_data = tp; 862 tty->driver_data = tp;
862 tty->winsize.ws_row = tp->view.rows - 2; 863 tty->winsize.ws_row = tp->view.rows - 2;
863 tty->winsize.ws_col = tp->view.cols; 864 tty->winsize.ws_col = tp->view.cols;
864 tty->low_latency = 0; 865 tty->low_latency = 0;
865 tp->tty = tty; 866 /* why to reassign? */
866 tp->kbd->tty = tty; 867 tty_port_tty_set(&tp->port, tty);
867 tp->inattr = TF_INPUT; 868 tp->inattr = TF_INPUT;
868 return 0; 869 return 0;
869 } 870 }
@@ -871,7 +872,7 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
871 tty3270_max_index = tty->index + 1; 872 tty3270_max_index = tty->index + 1;
872 873
873 /* Quick exit if there is no device for tty->index. */ 874 /* Quick exit if there is no device for tty->index. */
874 if (PTR_ERR(tp) == -ENODEV) 875 if (PTR_ERR(view) == -ENODEV)
875 return -ENODEV; 876 return -ENODEV;
876 877
877 /* Allocate tty3270 structure on first open. */ 878 /* Allocate tty3270 structure on first open. */
@@ -879,16 +880,6 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
879 if (IS_ERR(tp)) 880 if (IS_ERR(tp))
880 return PTR_ERR(tp); 881 return PTR_ERR(tp);
881 882
882 INIT_LIST_HEAD(&tp->lines);
883 INIT_LIST_HEAD(&tp->update);
884 INIT_LIST_HEAD(&tp->rcl_lines);
885 tp->rcl_max = 20;
886 setup_timer(&tp->timer, (void (*)(unsigned long)) tty3270_update,
887 (unsigned long) tp);
888 tasklet_init(&tp->readlet,
889 (void (*)(unsigned long)) tty3270_read_tasklet,
890 (unsigned long) tp->read);
891
892 rc = raw3270_add_view(&tp->view, &tty3270_fn, 883 rc = raw3270_add_view(&tp->view, &tty3270_fn,
893 tty->index + RAW3270_FIRSTMINOR); 884 tty->index + RAW3270_FIRSTMINOR);
894 if (rc) { 885 if (rc) {
@@ -903,7 +894,7 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
903 return rc; 894 return rc;
904 } 895 }
905 896
906 tp->tty = tty; 897 tty_port_tty_set(&tp->port, tty);
907 tty->low_latency = 0; 898 tty->low_latency = 0;
908 tty->driver_data = tp; 899 tty->driver_data = tp;
909 tty->winsize.ws_row = tp->view.rows - 2; 900 tty->winsize.ws_row = tp->view.rows - 2;
@@ -917,7 +908,7 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
917 for (i = 0; i < tp->view.rows - 2; i++) 908 for (i = 0; i < tp->view.rows - 2; i++)
918 tty3270_blank_line(tp); 909 tty3270_blank_line(tp);
919 910
920 tp->kbd->tty = tty; 911 tp->kbd->port = &tp->port;
921 tp->kbd->fn_handler[KVAL(K_INCRCONSOLE)] = tty3270_exit_tty; 912 tp->kbd->fn_handler[KVAL(K_INCRCONSOLE)] = tty3270_exit_tty;
922 tp->kbd->fn_handler[KVAL(K_SCROLLBACK)] = tty3270_scroll_backward; 913 tp->kbd->fn_handler[KVAL(K_SCROLLBACK)] = tty3270_scroll_backward;
923 tp->kbd->fn_handler[KVAL(K_SCROLLFORW)] = tty3270_scroll_forward; 914 tp->kbd->fn_handler[KVAL(K_SCROLLFORW)] = tty3270_scroll_forward;
@@ -935,14 +926,13 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
935static void 926static void
936tty3270_close(struct tty_struct *tty, struct file * filp) 927tty3270_close(struct tty_struct *tty, struct file * filp)
937{ 928{
938 struct tty3270 *tp; 929 struct tty3270 *tp = tty->driver_data;
939 930
940 if (tty->count > 1) 931 if (tty->count > 1)
941 return; 932 return;
942 tp = (struct tty3270 *) tty->driver_data;
943 if (tp) { 933 if (tp) {
944 tty->driver_data = NULL; 934 tty->driver_data = NULL;
945 tp->tty = tp->kbd->tty = NULL; 935 tty_port_tty_set(&tp->port, NULL);
946 raw3270_put_view(&tp->view); 936 raw3270_put_view(&tp->view);
947 } 937 }
948} 938}
@@ -1391,7 +1381,7 @@ tty3270_escape_sequence(struct tty3270 *tp, char ch)
1391 tty3270_lf(tp); 1381 tty3270_lf(tp);
1392 break; 1382 break;
1393 case 'Z': /* Respond ID. */ 1383 case 'Z': /* Respond ID. */
1394 kbd_puts_queue(tp->tty, "\033[?6c"); 1384 kbd_puts_queue(&tp->port, "\033[?6c");
1395 break; 1385 break;
1396 case '7': /* Save cursor position. */ 1386 case '7': /* Save cursor position. */
1397 tp->saved_cx = tp->cx; 1387 tp->saved_cx = tp->cx;
@@ -1437,11 +1427,11 @@ tty3270_escape_sequence(struct tty3270 *tp, char ch)
1437 tp->esc_state = ESnormal; 1427 tp->esc_state = ESnormal;
1438 if (ch == 'n' && !tp->esc_ques) { 1428 if (ch == 'n' && !tp->esc_ques) {
1439 if (tp->esc_par[0] == 5) /* Status report. */ 1429 if (tp->esc_par[0] == 5) /* Status report. */
1440 kbd_puts_queue(tp->tty, "\033[0n"); 1430 kbd_puts_queue(&tp->port, "\033[0n");
1441 else if (tp->esc_par[0] == 6) { /* Cursor report. */ 1431 else if (tp->esc_par[0] == 6) { /* Cursor report. */
1442 char buf[40]; 1432 char buf[40];
1443 sprintf(buf, "\033[%d;%dR", tp->cy + 1, tp->cx + 1); 1433 sprintf(buf, "\033[%d;%dR", tp->cy + 1, tp->cx + 1);
1444 kbd_puts_queue(tp->tty, buf); 1434 kbd_puts_queue(&tp->port, buf);
1445 } 1435 }
1446 return; 1436 return;
1447 } 1437 }
@@ -1513,12 +1503,13 @@ tty3270_escape_sequence(struct tty3270 *tp, char ch)
1513 * String write routine for 3270 ttys 1503 * String write routine for 3270 ttys
1514 */ 1504 */
1515static void 1505static void
1516tty3270_do_write(struct tty3270 *tp, const unsigned char *buf, int count) 1506tty3270_do_write(struct tty3270 *tp, struct tty_struct *tty,
1507 const unsigned char *buf, int count)
1517{ 1508{
1518 int i_msg, i; 1509 int i_msg, i;
1519 1510
1520 spin_lock_bh(&tp->view.lock); 1511 spin_lock_bh(&tp->view.lock);
1521 for (i_msg = 0; !tp->tty->stopped && i_msg < count; i_msg++) { 1512 for (i_msg = 0; !tty->stopped && i_msg < count; i_msg++) {
1522 if (tp->esc_state != 0) { 1513 if (tp->esc_state != 0) {
1523 /* Continue escape sequence. */ 1514 /* Continue escape sequence. */
1524 tty3270_escape_sequence(tp, buf[i_msg]); 1515 tty3270_escape_sequence(tp, buf[i_msg]);
@@ -1595,10 +1586,10 @@ tty3270_write(struct tty_struct * tty,
1595 if (!tp) 1586 if (!tp)
1596 return 0; 1587 return 0;
1597 if (tp->char_count > 0) { 1588 if (tp->char_count > 0) {
1598 tty3270_do_write(tp, tp->char_buf, tp->char_count); 1589 tty3270_do_write(tp, tty, tp->char_buf, tp->char_count);
1599 tp->char_count = 0; 1590 tp->char_count = 0;
1600 } 1591 }
1601 tty3270_do_write(tp, buf, count); 1592 tty3270_do_write(tp, tty, buf, count);
1602 return count; 1593 return count;
1603} 1594}
1604 1595
@@ -1629,7 +1620,7 @@ tty3270_flush_chars(struct tty_struct *tty)
1629 if (!tp) 1620 if (!tp)
1630 return; 1621 return;
1631 if (tp->char_count > 0) { 1622 if (tp->char_count > 0) {
1632 tty3270_do_write(tp, tp->char_buf, tp->char_count); 1623 tty3270_do_write(tp, tty, tp->char_buf, tp->char_count);
1633 tp->char_count = 0; 1624 tp->char_count = 0;
1634 } 1625 }
1635} 1626}