Commit 0146b693 authored by Jiri Slaby's avatar Jiri Slaby Committed by Greg Kroah-Hartman

TTY: HVC, use count from tty_port

Now, count is used from tty_port and protected by tty_port->lock.

n_outbuf is left unprotected in hvc_hangup now, because there is no
point to hold any lock, since other uses are unprotected too.
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 85bbc003
...@@ -313,18 +313,18 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) ...@@ -313,18 +313,18 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
if (!(hp = hvc_get_by_index(tty->index))) if (!(hp = hvc_get_by_index(tty->index)))
return -ENODEV; return -ENODEV;
spin_lock_irqsave(&hp->lock, flags); spin_lock_irqsave(&hp->port.lock, flags);
/* Check and then increment for fast path open. */ /* Check and then increment for fast path open. */
if (hp->count++ > 0) { if (hp->port.count++ > 0) {
spin_unlock_irqrestore(&hp->port.lock, flags);
/* FIXME why taking a reference here? */
tty_kref_get(tty); tty_kref_get(tty);
spin_unlock_irqrestore(&hp->lock, flags);
hvc_kick(); hvc_kick();
return 0; return 0;
} /* else count == 0 */ } /* else count == 0 */
spin_unlock_irqrestore(&hp->port.lock, flags);
tty->driver_data = hp; tty->driver_data = hp;
spin_unlock_irqrestore(&hp->lock, flags);
tty_port_tty_set(&hp->port, tty); tty_port_tty_set(&hp->port, tty);
if (hp->ops->notifier_add) if (hp->ops->notifier_add)
...@@ -367,10 +367,10 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) ...@@ -367,10 +367,10 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
hp = tty->driver_data; hp = tty->driver_data;
spin_lock_irqsave(&hp->lock, flags); spin_lock_irqsave(&hp->port.lock, flags);
if (--hp->count == 0) { if (--hp->port.count == 0) {
spin_unlock_irqrestore(&hp->lock, flags); spin_unlock_irqrestore(&hp->port.lock, flags);
/* We are done with the tty pointer now. */ /* We are done with the tty pointer now. */
tty_port_tty_set(&hp->port, NULL); tty_port_tty_set(&hp->port, NULL);
...@@ -387,10 +387,10 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) ...@@ -387,10 +387,10 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
*/ */
tty_wait_until_sent_from_close(tty, HVC_CLOSE_WAIT); tty_wait_until_sent_from_close(tty, HVC_CLOSE_WAIT);
} else { } else {
if (hp->count < 0) if (hp->port.count < 0)
printk(KERN_ERR "hvc_close %X: oops, count is %d\n", printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
hp->vtermno, hp->count); hp->vtermno, hp->port.count);
spin_unlock_irqrestore(&hp->lock, flags); spin_unlock_irqrestore(&hp->port.lock, flags);
} }
tty_kref_put(tty); tty_kref_put(tty);
...@@ -409,24 +409,25 @@ static void hvc_hangup(struct tty_struct *tty) ...@@ -409,24 +409,25 @@ static void hvc_hangup(struct tty_struct *tty)
/* cancel pending tty resize work */ /* cancel pending tty resize work */
cancel_work_sync(&hp->tty_resize); cancel_work_sync(&hp->tty_resize);
spin_lock_irqsave(&hp->lock, flags); spin_lock_irqsave(&hp->port.lock, flags);
/* /*
* The N_TTY line discipline has problems such that in a close vs * The N_TTY line discipline has problems such that in a close vs
* open->hangup case this can be called after the final close so prevent * open->hangup case this can be called after the final close so prevent
* that from happening for now. * that from happening for now.
*/ */
if (hp->count <= 0) { if (hp->port.count <= 0) {
spin_unlock_irqrestore(&hp->lock, flags); spin_unlock_irqrestore(&hp->port.lock, flags);
return; return;
} }
temp_open_count = hp->count; temp_open_count = hp->port.count;
hp->count = 0; hp->port.count = 0;
hp->n_outbuf = 0; spin_unlock_irqrestore(&hp->port.lock, flags);
spin_unlock_irqrestore(&hp->lock, flags);
tty_port_tty_set(&hp->port, NULL); tty_port_tty_set(&hp->port, NULL);
hp->n_outbuf = 0;
if (hp->ops->notifier_hangup) if (hp->ops->notifier_hangup)
hp->ops->notifier_hangup(hp, hp->data); hp->ops->notifier_hangup(hp, hp->data);
...@@ -474,7 +475,8 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count ...@@ -474,7 +475,8 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count
if (!hp) if (!hp)
return -EPIPE; return -EPIPE;
if (hp->count <= 0) /* FIXME what's this (unprotected) check for? */
if (hp->port.count <= 0)
return -EIO; return -EIO;
spin_lock_irqsave(&hp->lock, flags); spin_lock_irqsave(&hp->lock, flags);
......
...@@ -49,7 +49,6 @@ struct hvc_struct { ...@@ -49,7 +49,6 @@ struct hvc_struct {
struct tty_port port; struct tty_port port;
spinlock_t lock; spinlock_t lock;
int index; int index;
int count;
int do_wakeup; int do_wakeup;
char *outbuf; char *outbuf;
int outbuf_size; int outbuf_size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment