aboutsummaryrefslogtreecommitdiffstats
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)
downloadkernel_samsung_smdk4412-a360fae67bc173942f620d44d1b23cfb5ccaaf96.zip
kernel_samsung_smdk4412-a360fae67bc173942f620d44d1b23cfb5ccaaf96.tar.gz
kernel_samsung_smdk4412-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 8da976b..ac447c7 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);
}