aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/synclink_gt.c
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2010-06-01 16:52:50 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 16:47:41 -0400
commita360fae67bc173942f620d44d1b23cfb5ccaaf96 (patch)
treebe45781b50fb44586694e265d9ec113e481809f5 /drivers/char/synclink_gt.c
parent4287341d4dba27ef8048f589e3c0bc683c9f2017 (diff)
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/synclink_gt.c')
-rw-r--r--drivers/char/synclink_gt.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 3c7ac6a3ff80..5a602eb7cd2d 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -675,12 +675,14 @@ static int open(struct tty_struct *tty, struct file *filp)
675 goto cleanup; 675 goto cleanup;
676 } 676 }
677 677
678 mutex_lock(&info->port.mutex);
678 info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0; 679 info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
679 680
680 spin_lock_irqsave(&info->netlock, flags); 681 spin_lock_irqsave(&info->netlock, flags);
681 if (info->netcount) { 682 if (info->netcount) {
682 retval = -EBUSY; 683 retval = -EBUSY;
683 spin_unlock_irqrestore(&info->netlock, flags); 684 spin_unlock_irqrestore(&info->netlock, flags);
685 mutex_unlock(&info->port.mutex);
684 goto cleanup; 686 goto cleanup;
685 } 687 }
686 info->port.count++; 688 info->port.count++;
@@ -692,7 +694,7 @@ static int open(struct tty_struct *tty, struct file *filp)
692 if (retval < 0) 694 if (retval < 0)
693 goto cleanup; 695 goto cleanup;
694 } 696 }
695 697 mutex_unlock(&info->port.mutex);
696 retval = block_til_ready(tty, filp, info); 698 retval = block_til_ready(tty, filp, info);
697 if (retval) { 699 if (retval) {
698 DBGINFO(("%s block_til_ready rc=%d\n", info->device_name, retval)); 700 DBGINFO(("%s block_til_ready rc=%d\n", info->device_name, retval));
@@ -724,12 +726,14 @@ static void close(struct tty_struct *tty, struct file *filp)
724 if (tty_port_close_start(&info->port, tty, filp) == 0) 726 if (tty_port_close_start(&info->port, tty, filp) == 0)
725 goto cleanup; 727 goto cleanup;
726 728
729 mutex_lock(&info->port.mutex);
727 if (info->port.flags & ASYNC_INITIALIZED) 730 if (info->port.flags & ASYNC_INITIALIZED)
728 wait_until_sent(tty, info->timeout); 731 wait_until_sent(tty, info->timeout);
729 flush_buffer(tty); 732 flush_buffer(tty);
730 tty_ldisc_flush(tty); 733 tty_ldisc_flush(tty);
731 734
732 shutdown(info); 735 shutdown(info);
736 mutex_unlock(&info->port.mutex);
733 737
734 tty_port_close_end(&info->port, tty); 738 tty_port_close_end(&info->port, tty);
735 info->port.tty = NULL; 739 info->port.tty = NULL;
@@ -740,17 +744,23 @@ cleanup:
740static void hangup(struct tty_struct *tty) 744static void hangup(struct tty_struct *tty)
741{ 745{
742 struct slgt_info *info = tty->driver_data; 746 struct slgt_info *info = tty->driver_data;
747 unsigned long flags;
743 748
744 if (sanity_check(info, tty->name, "hangup")) 749 if (sanity_check(info, tty->name, "hangup"))
745 return; 750 return;
746 DBGINFO(("%s hangup\n", info->device_name)); 751 DBGINFO(("%s hangup\n", info->device_name));
747 752
748 flush_buffer(tty); 753 flush_buffer(tty);
754
755 mutex_lock(&info->port.mutex);
749 shutdown(info); 756 shutdown(info);
750 757
758 spin_lock_irqsave(&info->port.lock, flags);
751 info->port.count = 0; 759 info->port.count = 0;
752 info->port.flags &= ~ASYNC_NORMAL_ACTIVE; 760 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
753 info->port.tty = NULL; 761 info->port.tty = NULL;
762 spin_unlock_irqrestore(&info->port.lock, flags);
763 mutex_unlock(&info->port.mutex);
754 764
755 wake_up_interruptible(&info->port.open_wait); 765 wake_up_interruptible(&info->port.open_wait);
756} 766}