diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 19:12:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 19:12:24 -0400 |
commit | 94b5aff4c6f72fee6b0f49d49e4fa8b204e8ded9 (patch) | |
tree | 39197121b6ef8cddaa0f4057fe24b4ced58e8982 /drivers/s390 | |
parent | 5d4e2d08e7fdf7339f84a1c670d296a77e02f881 (diff) | |
parent | 59bd234b72fc29887839d792b7d6c7e8d2a577a6 (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.c | 142 | ||||
-rw-r--r-- | drivers/s390/char/keyboard.c | 30 | ||||
-rw-r--r-- | drivers/s390/char/keyboard.h | 14 | ||||
-rw-r--r-- | drivers/s390/char/sclp_tty.c | 33 | ||||
-rw-r--r-- | drivers/s390/char/sclp_vt220.c | 33 | ||||
-rw-r--r-- | drivers/s390/char/tty3270.c | 121 |
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 | ||
78 | struct raw3215_info { | 76 | struct 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 | */ |
310 | static inline void raw3215_try_io(struct raw3215_info *raw) | 308 | static 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) | |||
340 | static void raw3215_wakeup(unsigned long data) | 336 | static 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 | */ |
349 | static void raw3215_next_io(struct raw3215_info *raw) | 349 | static 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; | 456 | put_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 | ||
653 | static 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 | |||
676 | static void raw3215_free_info(struct raw3215_info *raw) | ||
677 | { | ||
678 | kfree(raw->inbuf); | ||
679 | kfree(raw->buffer); | ||
680 | kfree(raw); | ||
681 | } | ||
682 | |||
651 | static int raw3215_probe (struct ccw_device *cdev) | 683 | static 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 | |||
239 | k_fn(struct kbd_data *kbd, unsigned char value) | 239 | k_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 | ||
245 | static void | 245 | static 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 | */ |
259 | static void | 259 | static void |
260 | to_utf8(struct tty_struct *tty, ushort c) | 260 | to_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 | ||
458 | int kbd_ioctl(struct kbd_data *kbd, unsigned int cmd, unsigned long arg) | 458 | int 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 | ||
23 | struct kbd_data { | 23 | struct 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 | */ |
44 | static inline void | 44 | static inline void |
45 | kbd_put_queue(struct tty_struct *tty, int ch) | 45 | kbd_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 | ||
51 | static inline void | 55 | static inline void |
52 | kbd_puts_queue(struct tty_struct *tty, char *cp) | 56 | kbd_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. */ |
49 | static struct timer_list sclp_tty_timer; | 49 | static struct timer_list sclp_tty_timer; |
50 | 50 | ||
51 | static struct tty_struct *sclp_tty; | 51 | static struct tty_port sclp_port; |
52 | static unsigned char sclp_tty_chars[SCLP_TTY_BUF_SIZE]; | 52 | static unsigned char sclp_tty_chars[SCLP_TTY_BUF_SIZE]; |
53 | static unsigned short int sclp_tty_chars_count; | 53 | static unsigned short int sclp_tty_chars_count; |
54 | 54 | ||
@@ -64,7 +64,7 @@ static int sclp_tty_columns = 80; | |||
64 | static int | 64 | static int |
65 | sclp_tty_open(struct tty_struct *tty, struct file *filp) | 65 | sclp_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) | |||
108 | static void | 108 | static void |
109 | sclp_ttybuf_callback(struct sclp_buffer *buffer, int rc) | 109 | sclp_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) | |||
326 | static void | 329 | static void |
327 | sclp_tty_input(unsigned char* buf, unsigned int count) | 330 | sclp_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 */ |
40 | struct sclp_vt220_request { | 39 | struct 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 */ |
57 | static struct tty_driver *sclp_vt220_driver; | 56 | static struct tty_driver *sclp_vt220_driver; |
58 | 57 | ||
59 | /* The tty_struct that the kernel associated with us */ | 58 | static struct tty_port sclp_vt220_port; |
60 | static 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 */ |
63 | static spinlock_t sclp_vt220_lock; | 61 | static spinlock_t sclp_vt220_lock; |
@@ -116,6 +114,7 @@ static struct sclp_register sclp_vt220_register = { | |||
116 | static void | 114 | static void |
117 | sclp_vt220_process_queue(struct sclp_vt220_request *request) | 115 | sclp_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) | |||
460 | static void | 461 | static void |
461 | sclp_vt220_receiver_fn(struct evbuf_header *evbuf) | 462 | sclp_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 | |||
491 | sclp_vt220_open(struct tty_struct *tty, struct file *filp) | 494 | sclp_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) | |||
510 | static void | 510 | static void |
511 | sclp_vt220_close(struct tty_struct *tty, struct file *filp) | 511 | sclp_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 | */ |
62 | struct tty3270 { | 62 | struct 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) | |||
324 | static void | 324 | static void |
325 | tty3270_write_callback(struct raw3270_request *rq, void *data) | 325 | tty3270_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) | |||
450 | static void | 449 | static void |
451 | tty3270_rcl_backward(struct kbd_data *kbd) | 450 | tty3270_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) | |||
478 | static void | 476 | static void |
479 | tty3270_exit_tty(struct kbd_data *kbd) | 477 | tty3270_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) | |||
490 | static void | 487 | static void |
491 | tty3270_scroll_forward(struct kbd_data *kbd) | 488 | tty3270_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) | |||
513 | static void | 509 | static void |
514 | tty3270_scroll_backward(struct kbd_data *kbd) | 510 | tty3270_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 | |||
537 | tty3270_read_tasklet(struct raw3270_request *rrq) | 532 | tty3270_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) | |||
596 | static void | 587 | static void |
597 | tty3270_read_callback(struct raw3270_request *rq, void *data) | 588 | tty3270_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) | |||
635 | static int | 627 | static int |
636 | tty3270_activate(struct raw3270_view *view) | 628 | tty3270_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) | |||
646 | static void | 637 | static void |
647 | tty3270_deactivate(struct raw3270_view *view) | 638 | tty3270_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) | |||
794 | static void | 795 | static void |
795 | tty3270_release(struct raw3270_view *view) | 796 | tty3270_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) | |||
813 | static void | 813 | static void |
814 | tty3270_free(struct raw3270_view *view) | 814 | tty3270_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) | |||
823 | static void | 824 | static void |
824 | tty3270_del_views(void) | 825 | tty3270_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 = { | |||
848 | static int | 848 | static int |
849 | tty3270_open(struct tty_struct *tty, struct file * filp) | 849 | tty3270_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) | |||
935 | static void | 926 | static void |
936 | tty3270_close(struct tty_struct *tty, struct file * filp) | 927 | tty3270_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 | */ |
1515 | static void | 1505 | static void |
1516 | tty3270_do_write(struct tty3270 *tp, const unsigned char *buf, int count) | 1506 | tty3270_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 | } |