summaryrefslogtreecommitdiffstats
path: root/drivers/char/synclinkmp.c
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2010-06-01 22:52:50 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 13:47:41 -0700
commita360fae67bc173942f620d44d1b23cfb5ccaaf96 (patch)
treebe45781b50fb44586694e265d9ec113e481809f5 /drivers/char/synclinkmp.c
parent4287341d4dba27ef8048f589e3c0bc683c9f2017 (diff)
downloadlinux-a360fae67bc173942f620d44d1b23cfb5ccaaf96.tar.bz2
synclink: reworking locking a bit
Use the port mutex and port lock to fix the various races. The locking still isn't totally consistent but its better than before. Wants switching to the port helpers. Signed-off-by: Alan Cox <alan@linux.intel.com> Cc: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/char/synclinkmp.c')
-rw-r--r--drivers/char/synclinkmp.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 8da976bd7314..ac447c7eb572 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -812,13 +812,15 @@ static void close(struct tty_struct *tty, struct file *filp)
if (tty_port_close_start(&info->port, tty, filp) == 0)
goto cleanup;
-
+
+ mutex_lock(&info->port.mutex);
if (info->port.flags & ASYNC_INITIALIZED)
wait_until_sent(tty, info->timeout);
flush_buffer(tty);
tty_ldisc_flush(tty);
shutdown(info);
+ mutex_unlock(&info->port.mutex);
tty_port_close_end(&info->port, tty);
info->port.tty = NULL;
@@ -834,6 +836,7 @@ cleanup:
static void hangup(struct tty_struct *tty)
{
SLMP_INFO *info = tty->driver_data;
+ unsigned long flags;
if (debug_level >= DEBUG_LEVEL_INFO)
printk("%s(%d):%s hangup()\n",
@@ -842,12 +845,16 @@ static void hangup(struct tty_struct *tty)
if (sanity_check(info, tty->name, "hangup"))
return;
+ mutex_lock(&info->port.mutex);
flush_buffer(tty);
shutdown(info);
+ spin_lock_irqsave(&info->port.lock, flags);
info->port.count = 0;
info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
info->port.tty = NULL;
+ spin_unlock_irqrestore(&info->port.lock, flags);
+ mutex_unlock(&info->port.mutex);
wake_up_interruptible(&info->port.open_wait);
}