TTY: con3215, use tty from tty_port

Obtain tty_struct only once in ISR and pass it down to
raw3215_next_io. Other than that, we just use the tty with raised
reference. And set it properly in open and close.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Jiri Slaby 2012-04-11 11:14:59 +02:00 committed by Greg Kroah-Hartman
parent 8dd360f042
commit 86b26007a3

View File

@ -83,7 +83,6 @@ struct raw3215_info {
int head; /* first free byte in output buffer */ int head; /* first free byte in output buffer */
int count; /* number of bytes in output buffer */ int count; /* number of bytes in output buffer */
int written; /* number of bytes in write requests */ int written; /* number of bytes in write requests */
struct tty_struct *tty; /* pointer to tty structure if present */
struct raw3215_req *queued_read; /* pointer to queued read requests */ struct raw3215_req *queued_read; /* pointer to queued read requests */
struct raw3215_req *queued_write;/* pointer to queued write requests */ struct raw3215_req *queued_write;/* pointer to queued write requests */
struct tasklet_struct tlet; /* tasklet to invoke tty_wakeup */ struct tasklet_struct tlet; /* tasklet to invoke tty_wakeup */
@ -343,11 +342,11 @@ static void raw3215_wakeup(unsigned long data)
/* /*
* Try to start the next IO and wake up processes waiting on the tty. * Try to start the next IO and wake up processes waiting on the tty.
*/ */
static void raw3215_next_io(struct raw3215_info *raw) static void raw3215_next_io(struct raw3215_info *raw, struct tty_struct *tty)
{ {
raw3215_mk_write_req(raw); raw3215_mk_write_req(raw);
raw3215_try_io(raw); raw3215_try_io(raw);
if (raw->tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) if (tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE)
tasklet_schedule(&raw->tlet); tasklet_schedule(&raw->tlet);
} }
@ -365,10 +364,11 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
raw = dev_get_drvdata(&cdev->dev); raw = dev_get_drvdata(&cdev->dev);
req = (struct raw3215_req *) intparm; req = (struct raw3215_req *) intparm;
tty = tty_port_tty_get(&raw->port);
cstat = irb->scsw.cmd.cstat; cstat = irb->scsw.cmd.cstat;
dstat = irb->scsw.cmd.dstat; dstat = irb->scsw.cmd.dstat;
if (cstat != 0) if (cstat != 0)
raw3215_next_io(raw); raw3215_next_io(raw, tty);
if (dstat & 0x01) { /* we got a unit exception */ if (dstat & 0x01) { /* we got a unit exception */
dstat &= ~0x01; /* we can ignore it */ dstat &= ~0x01; /* we can ignore it */
} }
@ -378,13 +378,13 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
break; break;
/* Attention interrupt, someone hit the enter key */ /* Attention interrupt, someone hit the enter key */
raw3215_mk_read_req(raw); raw3215_mk_read_req(raw);
raw3215_next_io(raw); raw3215_next_io(raw, tty);
break; break;
case 0x08: case 0x08:
case 0x0C: case 0x0C:
/* Channel end interrupt. */ /* Channel end interrupt. */
if ((raw = req->info) == NULL) if ((raw = req->info) == NULL)
return; /* That shouldn't happen ... */ goto put_tty; /* That shouldn't happen ... */
if (req->type == RAW3215_READ) { if (req->type == RAW3215_READ) {
/* store residual count, then wait for device end */ /* store residual count, then wait for device end */
req->residual = irb->scsw.cmd.count; req->residual = irb->scsw.cmd.count;
@ -394,11 +394,10 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
case 0x04: case 0x04:
/* Device end interrupt. */ /* Device end interrupt. */
if ((raw = req->info) == NULL) if ((raw = req->info) == NULL)
return; /* That shouldn't happen ... */ goto put_tty; /* That shouldn't happen ... */
if (req->type == RAW3215_READ && raw->tty != NULL) { if (req->type == RAW3215_READ && tty != NULL) {
unsigned int cchar; unsigned int cchar;
tty = raw->tty;
count = 160 - req->residual; count = 160 - req->residual;
EBCASC(raw->inbuf, count); EBCASC(raw->inbuf, count);
cchar = ctrlchar_handle(raw->inbuf, count, tty); cchar = ctrlchar_handle(raw->inbuf, count, tty);
@ -408,7 +407,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
case CTRLCHAR_CTRL: case CTRLCHAR_CTRL:
tty_insert_flip_char(tty, cchar, TTY_NORMAL); tty_insert_flip_char(tty, cchar, TTY_NORMAL);
tty_flip_buffer_push(raw->tty); tty_flip_buffer_push(tty);
break; break;
case CTRLCHAR_NONE: case CTRLCHAR_NONE:
@ -421,7 +420,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
} else } else
count -= 2; count -= 2;
tty_insert_flip_string(tty, raw->inbuf, count); tty_insert_flip_string(tty, raw->inbuf, count);
tty_flip_buffer_push(raw->tty); tty_flip_buffer_push(tty);
break; break;
} }
} else if (req->type == RAW3215_WRITE) { } else if (req->type == RAW3215_WRITE) {
@ -436,7 +435,7 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
raw->queued_read == NULL) { raw->queued_read == NULL) {
wake_up_interruptible(&raw->empty_wait); wake_up_interruptible(&raw->empty_wait);
} }
raw3215_next_io(raw); raw3215_next_io(raw, tty);
break; break;
default: default:
/* Strange interrupt, I'll do my best to clean up */ /* Strange interrupt, I'll do my best to clean up */
@ -448,9 +447,10 @@ static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
raw->flags &= ~RAW3215_WORKING; raw->flags &= ~RAW3215_WORKING;
raw3215_free_req(req); raw3215_free_req(req);
} }
raw3215_next_io(raw); raw3215_next_io(raw, tty);
} }
return; put_tty:
tty_kref_put(tty);
} }
/* /*
@ -946,7 +946,7 @@ static int tty3215_open(struct tty_struct *tty, struct file * filp)
return -ENODEV; return -ENODEV;
tty->driver_data = raw; tty->driver_data = raw;
raw->tty = tty; tty_port_tty_set(&raw->port, tty);
tty->low_latency = 0; /* don't use bottom half for pushing chars */ tty->low_latency = 0; /* don't use bottom half for pushing chars */
/* /*
@ -977,7 +977,7 @@ static void tty3215_close(struct tty_struct *tty, struct file * filp)
raw3215_shutdown(raw); raw3215_shutdown(raw);
tasklet_kill(&raw->tlet); tasklet_kill(&raw->tlet);
tty->closing = 0; tty->closing = 0;
raw->tty = NULL; tty_port_tty_set(&raw->port, NULL);
} }
/* /*