aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/synclink_gt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/synclink_gt.c')
-rw-r--r--drivers/char/synclink_gt.c92
1 files changed, 47 insertions, 45 deletions
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 334cf5c8c8b6..fef80cfcab5c 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -40,8 +40,8 @@
40#define DBGBH(fmt) if (debug_level >= DEBUG_LEVEL_BH) printk fmt 40#define DBGBH(fmt) if (debug_level >= DEBUG_LEVEL_BH) printk fmt
41#define DBGISR(fmt) if (debug_level >= DEBUG_LEVEL_ISR) printk fmt 41#define DBGISR(fmt) if (debug_level >= DEBUG_LEVEL_ISR) printk fmt
42#define DBGDATA(info, buf, size, label) if (debug_level >= DEBUG_LEVEL_DATA) trace_block((info), (buf), (size), (label)) 42#define DBGDATA(info, buf, size, label) if (debug_level >= DEBUG_LEVEL_DATA) trace_block((info), (buf), (size), (label))
43//#define DBGTBUF(info) dump_tbufs(info) 43/*#define DBGTBUF(info) dump_tbufs(info)*/
44//#define DBGRBUF(info) dump_rbufs(info) 44/*#define DBGRBUF(info) dump_rbufs(info)*/
45 45
46 46
47#include <linux/module.h> 47#include <linux/module.h>
@@ -62,7 +62,6 @@
62#include <linux/mm.h> 62#include <linux/mm.h>
63#include <linux/seq_file.h> 63#include <linux/seq_file.h>
64#include <linux/slab.h> 64#include <linux/slab.h>
65#include <linux/smp_lock.h>
66#include <linux/netdevice.h> 65#include <linux/netdevice.h>
67#include <linux/vmalloc.h> 66#include <linux/vmalloc.h>
68#include <linux/init.h> 67#include <linux/init.h>
@@ -676,12 +675,14 @@ static int open(struct tty_struct *tty, struct file *filp)
676 goto cleanup; 675 goto cleanup;
677 } 676 }
678 677
678 mutex_lock(&info->port.mutex);
679 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;
680 680
681 spin_lock_irqsave(&info->netlock, flags); 681 spin_lock_irqsave(&info->netlock, flags);
682 if (info->netcount) { 682 if (info->netcount) {
683 retval = -EBUSY; 683 retval = -EBUSY;
684 spin_unlock_irqrestore(&info->netlock, flags); 684 spin_unlock_irqrestore(&info->netlock, flags);
685 mutex_unlock(&info->port.mutex);
685 goto cleanup; 686 goto cleanup;
686 } 687 }
687 info->port.count++; 688 info->port.count++;
@@ -693,7 +694,7 @@ static int open(struct tty_struct *tty, struct file *filp)
693 if (retval < 0) 694 if (retval < 0)
694 goto cleanup; 695 goto cleanup;
695 } 696 }
696 697 mutex_unlock(&info->port.mutex);
697 retval = block_til_ready(tty, filp, info); 698 retval = block_til_ready(tty, filp, info);
698 if (retval) { 699 if (retval) {
699 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));
@@ -725,12 +726,14 @@ static void close(struct tty_struct *tty, struct file *filp)
725 if (tty_port_close_start(&info->port, tty, filp) == 0) 726 if (tty_port_close_start(&info->port, tty, filp) == 0)
726 goto cleanup; 727 goto cleanup;
727 728
729 mutex_lock(&info->port.mutex);
728 if (info->port.flags & ASYNC_INITIALIZED) 730 if (info->port.flags & ASYNC_INITIALIZED)
729 wait_until_sent(tty, info->timeout); 731 wait_until_sent(tty, info->timeout);
730 flush_buffer(tty); 732 flush_buffer(tty);
731 tty_ldisc_flush(tty); 733 tty_ldisc_flush(tty);
732 734
733 shutdown(info); 735 shutdown(info);
736 mutex_unlock(&info->port.mutex);
734 737
735 tty_port_close_end(&info->port, tty); 738 tty_port_close_end(&info->port, tty);
736 info->port.tty = NULL; 739 info->port.tty = NULL;
@@ -741,17 +744,23 @@ cleanup:
741static void hangup(struct tty_struct *tty) 744static void hangup(struct tty_struct *tty)
742{ 745{
743 struct slgt_info *info = tty->driver_data; 746 struct slgt_info *info = tty->driver_data;
747 unsigned long flags;
744 748
745 if (sanity_check(info, tty->name, "hangup")) 749 if (sanity_check(info, tty->name, "hangup"))
746 return; 750 return;
747 DBGINFO(("%s hangup\n", info->device_name)); 751 DBGINFO(("%s hangup\n", info->device_name));
748 752
749 flush_buffer(tty); 753 flush_buffer(tty);
754
755 mutex_lock(&info->port.mutex);
750 shutdown(info); 756 shutdown(info);
751 757
758 spin_lock_irqsave(&info->port.lock, flags);
752 info->port.count = 0; 759 info->port.count = 0;
753 info->port.flags &= ~ASYNC_NORMAL_ACTIVE; 760 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
754 info->port.tty = NULL; 761 info->port.tty = NULL;
762 spin_unlock_irqrestore(&info->port.lock, flags);
763 mutex_unlock(&info->port.mutex);
755 764
756 wake_up_interruptible(&info->port.open_wait); 765 wake_up_interruptible(&info->port.open_wait);
757} 766}
@@ -901,8 +910,6 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
901 * Note: use tight timings here to satisfy the NIST-PCTS. 910 * Note: use tight timings here to satisfy the NIST-PCTS.
902 */ 911 */
903 912
904 lock_kernel();
905
906 if (info->params.data_rate) { 913 if (info->params.data_rate) {
907 char_time = info->timeout/(32 * 5); 914 char_time = info->timeout/(32 * 5);
908 if (!char_time) 915 if (!char_time)
@@ -920,8 +927,6 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
920 if (timeout && time_after(jiffies, orig_jiffies + timeout)) 927 if (timeout && time_after(jiffies, orig_jiffies + timeout))
921 break; 928 break;
922 } 929 }
923 unlock_kernel();
924
925exit: 930exit:
926 DBGINFO(("%s wait_until_sent exit\n", info->device_name)); 931 DBGINFO(("%s wait_until_sent exit\n", info->device_name));
927} 932}
@@ -1041,8 +1046,37 @@ static int ioctl(struct tty_struct *tty, struct file *file,
1041 return -EIO; 1046 return -EIO;
1042 } 1047 }
1043 1048
1044 lock_kernel(); 1049 switch (cmd) {
1045 1050 case MGSL_IOCWAITEVENT:
1051 return wait_mgsl_event(info, argp);
1052 case TIOCMIWAIT:
1053 return modem_input_wait(info,(int)arg);
1054 case TIOCGICOUNT:
1055 spin_lock_irqsave(&info->lock,flags);
1056 cnow = info->icount;
1057 spin_unlock_irqrestore(&info->lock,flags);
1058 p_cuser = argp;
1059 if (put_user(cnow.cts, &p_cuser->cts) ||
1060 put_user(cnow.dsr, &p_cuser->dsr) ||
1061 put_user(cnow.rng, &p_cuser->rng) ||
1062 put_user(cnow.dcd, &p_cuser->dcd) ||
1063 put_user(cnow.rx, &p_cuser->rx) ||
1064 put_user(cnow.tx, &p_cuser->tx) ||
1065 put_user(cnow.frame, &p_cuser->frame) ||
1066 put_user(cnow.overrun, &p_cuser->overrun) ||
1067 put_user(cnow.parity, &p_cuser->parity) ||
1068 put_user(cnow.brk, &p_cuser->brk) ||
1069 put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
1070 return -EFAULT;
1071 return 0;
1072 case MGSL_IOCSGPIO:
1073 return set_gpio(info, argp);
1074 case MGSL_IOCGGPIO:
1075 return get_gpio(info, argp);
1076 case MGSL_IOCWAITGPIO:
1077 return wait_gpio(info, argp);
1078 }
1079 mutex_lock(&info->port.mutex);
1046 switch (cmd) { 1080 switch (cmd) {
1047 case MGSL_IOCGPARAMS: 1081 case MGSL_IOCGPARAMS:
1048 ret = get_params(info, argp); 1082 ret = get_params(info, argp);
@@ -1068,50 +1102,16 @@ static int ioctl(struct tty_struct *tty, struct file *file,
1068 case MGSL_IOCGSTATS: 1102 case MGSL_IOCGSTATS:
1069 ret = get_stats(info, argp); 1103 ret = get_stats(info, argp);
1070 break; 1104 break;
1071 case MGSL_IOCWAITEVENT:
1072 ret = wait_mgsl_event(info, argp);
1073 break;
1074 case TIOCMIWAIT:
1075 ret = modem_input_wait(info,(int)arg);
1076 break;
1077 case MGSL_IOCGIF: 1105 case MGSL_IOCGIF:
1078 ret = get_interface(info, argp); 1106 ret = get_interface(info, argp);
1079 break; 1107 break;
1080 case MGSL_IOCSIF: 1108 case MGSL_IOCSIF:
1081 ret = set_interface(info,(int)arg); 1109 ret = set_interface(info,(int)arg);
1082 break; 1110 break;
1083 case MGSL_IOCSGPIO:
1084 ret = set_gpio(info, argp);
1085 break;
1086 case MGSL_IOCGGPIO:
1087 ret = get_gpio(info, argp);
1088 break;
1089 case MGSL_IOCWAITGPIO:
1090 ret = wait_gpio(info, argp);
1091 break;
1092 case TIOCGICOUNT:
1093 spin_lock_irqsave(&info->lock,flags);
1094 cnow = info->icount;
1095 spin_unlock_irqrestore(&info->lock,flags);
1096 p_cuser = argp;
1097 if (put_user(cnow.cts, &p_cuser->cts) ||
1098 put_user(cnow.dsr, &p_cuser->dsr) ||
1099 put_user(cnow.rng, &p_cuser->rng) ||
1100 put_user(cnow.dcd, &p_cuser->dcd) ||
1101 put_user(cnow.rx, &p_cuser->rx) ||
1102 put_user(cnow.tx, &p_cuser->tx) ||
1103 put_user(cnow.frame, &p_cuser->frame) ||
1104 put_user(cnow.overrun, &p_cuser->overrun) ||
1105 put_user(cnow.parity, &p_cuser->parity) ||
1106 put_user(cnow.brk, &p_cuser->brk) ||
1107 put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
1108 ret = -EFAULT;
1109 ret = 0;
1110 break;
1111 default: 1111 default:
1112 ret = -ENOIOCTLCMD; 1112 ret = -ENOIOCTLCMD;
1113 } 1113 }
1114 unlock_kernel(); 1114 mutex_unlock(&info->port.mutex);
1115 return ret; 1115 return ret;
1116} 1116}
1117 1117
@@ -3244,7 +3244,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3244 } 3244 }
3245 3245
3246 DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); 3246 DBGINFO(("%s block_til_ready wait\n", tty->driver->name));
3247 tty_unlock();
3247 schedule(); 3248 schedule();
3249 tty_lock();
3248 } 3250 }
3249 3251
3250 set_current_state(TASK_RUNNING); 3252 set_current_state(TASK_RUNNING);