diff options
author | Alan Cox <alan@linux.intel.com> | 2009-10-06 11:06:11 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 18:18:04 -0500 |
commit | 64bc397914265a9ead8d73b63bb31ab3bdd25f67 (patch) | |
tree | dc96d1737d3d70bbdebaea7e0f0aedd1377e1000 /drivers/char | |
parent | 894cb91770f7794f1a17db4df2d83999b197da24 (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.c | 36 |
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 | ||
100 | static void tty_port_shutdown(struct tty_port *port) | 100 | static 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 | } |
383 | EXPORT_SYMBOL(tty_port_close); | 384 | EXPORT_SYMBOL(tty_port_close); |
385 | |||
386 | int 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 | |||
417 | EXPORT_SYMBOL(tty_port_open); | ||