aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/char/synclink_gt.c12
-rw-r--r--drivers/char/synclinkmp.c9
2 files changed, 19 insertions, 2 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}
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)
812 812
813 if (tty_port_close_start(&info->port, tty, filp) == 0) 813 if (tty_port_close_start(&info->port, tty, filp) == 0)
814 goto cleanup; 814 goto cleanup;
815 815
816 mutex_lock(&info->port.mutex);
816 if (info->port.flags & ASYNC_INITIALIZED) 817 if (info->port.flags & ASYNC_INITIALIZED)
817 wait_until_sent(tty, info->timeout); 818 wait_until_sent(tty, info->timeout);
818 819
819 flush_buffer(tty); 820 flush_buffer(tty);
820 tty_ldisc_flush(tty); 821 tty_ldisc_flush(tty);
821 shutdown(info); 822 shutdown(info);
823 mutex_unlock(&info->port.mutex);
822 824
823 tty_port_close_end(&info->port, tty); 825 tty_port_close_end(&info->port, tty);
824 info->port.tty = NULL; 826 info->port.tty = NULL;
@@ -834,6 +836,7 @@ cleanup:
834static void hangup(struct tty_struct *tty) 836static void hangup(struct tty_struct *tty)
835{ 837{
836 SLMP_INFO *info = tty->driver_data; 838 SLMP_INFO *info = tty->driver_data;
839 unsigned long flags;
837 840
838 if (debug_level >= DEBUG_LEVEL_INFO) 841 if (debug_level >= DEBUG_LEVEL_INFO)
839 printk("%s(%d):%s hangup()\n", 842 printk("%s(%d):%s hangup()\n",
@@ -842,12 +845,16 @@ static void hangup(struct tty_struct *tty)
842 if (sanity_check(info, tty->name, "hangup")) 845 if (sanity_check(info, tty->name, "hangup"))
843 return; 846 return;
844 847
848 mutex_lock(&info->port.mutex);
845 flush_buffer(tty); 849 flush_buffer(tty);
846 shutdown(info); 850 shutdown(info);
847 851
852 spin_lock_irqsave(&info->port.lock, flags);
848 info->port.count = 0; 853 info->port.count = 0;
849 info->port.flags &= ~ASYNC_NORMAL_ACTIVE; 854 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
850 info->port.tty = NULL; 855 info->port.tty = NULL;
856 spin_unlock_irqrestore(&info->port.lock, flags);
857 mutex_unlock(&info->port.mutex);
851 858
852 wake_up_interruptible(&info->port.open_wait); 859 wake_up_interruptible(&info->port.open_wait);
853} 860}