aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2009-10-06 11:06:11 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 18:18:04 -0500
commit64bc397914265a9ead8d73b63bb31ab3bdd25f67 (patch)
treedc96d1737d3d70bbdebaea7e0f0aedd1377e1000 /drivers/char
parent894cb91770f7794f1a17db4df2d83999b197da24 (diff)
tty_port: add "tty_port_open" helper
For the moment this just moves the USB logic over and fixes the 'what if we open and hangup at the same time' race noticed by Oliver Neukum. Signed-off-by: Alan Cox <alan@linux.intel.com> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: Oliver Neukum <oliver@neukum.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/tty_port.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index c63f3d33914a..b22a61a4fbe5 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -99,10 +99,11 @@ EXPORT_SYMBOL(tty_port_tty_set);
99 99
100static void tty_port_shutdown(struct tty_port *port) 100static void tty_port_shutdown(struct tty_port *port)
101{ 101{
102 mutex_lock(&port->mutex);
102 if (port->ops->shutdown && 103 if (port->ops->shutdown &&
103 test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags)) 104 test_and_clear_bit(ASYNCB_INITIALIZED, &port->flags))
104 port->ops->shutdown(port); 105 port->ops->shutdown(port);
105 106 mutex_unlock(&port->mutex);
106} 107}
107 108
108/** 109/**
@@ -381,3 +382,36 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty,
381 tty_port_tty_set(port, NULL); 382 tty_port_tty_set(port, NULL);
382} 383}
383EXPORT_SYMBOL(tty_port_close); 384EXPORT_SYMBOL(tty_port_close);
385
386int tty_port_open(struct tty_port *port, struct tty_struct *tty,
387 struct file *filp)
388{
389 spin_lock_irq(&port->lock);
390 if (!tty_hung_up_p(filp))
391 ++port->count;
392 spin_unlock_irq(&port->lock);
393 tty_port_tty_set(port, tty);
394
395 /*
396 * Do the device-specific open only if the hardware isn't
397 * already initialized. Serialize open and shutdown using the
398 * port mutex.
399 */
400
401 mutex_lock(&port->mutex);
402
403 if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
404 if (port->ops->activate) {
405 int retval = port->ops->activate(port, tty);
406 if (retval) {
407 mutex_unlock(&port->mutex);
408 return retval;
409 }
410 }
411 set_bit(ASYNCB_INITIALIZED, &port->flags);
412 }
413 mutex_unlock(&port->mutex);
414 return tty_port_block_til_ready(port, tty, filp);
415}
416
417EXPORT_SYMBOL(tty_port_open);