aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2010-06-01 16:52:46 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 16:47:40 -0400
commitf602501d90e0da28c8e6f5e4569b8bf5d40a9d9c (patch)
treeae0bfcf04f6ef9f4a374b5105d59c1830776d209 /drivers/char
parent417b6e0e146ba38eec5d79777433e38c73d4feb1 (diff)
synclink: kill the big kernel lock
We don't need it while waiting and we can lock the ioctls using the port mutex. While at it eliminate use of the hangup mutex and switch to the port mutex. 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')
-rw-r--r--drivers/char/synclink.c19
-rw-r--r--drivers/char/synclink_gt.c78
-rw-r--r--drivers/char/synclinkmp.c32
3 files changed, 56 insertions, 73 deletions
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 0658fc548222..2b03d4d47350 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -81,7 +81,6 @@
81#include <linux/mm.h> 81#include <linux/mm.h>
82#include <linux/seq_file.h> 82#include <linux/seq_file.h>
83#include <linux/slab.h> 83#include <linux/slab.h>
84#include <linux/smp_lock.h>
85#include <linux/delay.h> 84#include <linux/delay.h>
86#include <linux/netdevice.h> 85#include <linux/netdevice.h>
87#include <linux/vmalloc.h> 86#include <linux/vmalloc.h>
@@ -2436,7 +2435,9 @@ static int mgsl_get_stats(struct mgsl_struct * info, struct mgsl_icount __user *
2436 if (!user_icount) { 2435 if (!user_icount) {
2437 memset(&info->icount, 0, sizeof(info->icount)); 2436 memset(&info->icount, 0, sizeof(info->icount));
2438 } else { 2437 } else {
2438 mutex_lock(&info->port.mutex);
2439 COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); 2439 COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
2440 mutex_unlock(&info->port.mutex);
2440 if (err) 2441 if (err)
2441 return -EFAULT; 2442 return -EFAULT;
2442 } 2443 }
@@ -2461,7 +2462,9 @@ static int mgsl_get_params(struct mgsl_struct * info, MGSL_PARAMS __user *user_p
2461 printk("%s(%d):mgsl_get_params(%s)\n", 2462 printk("%s(%d):mgsl_get_params(%s)\n",
2462 __FILE__,__LINE__, info->device_name); 2463 __FILE__,__LINE__, info->device_name);
2463 2464
2465 mutex_lock(&info->port.mutex);
2464 COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); 2466 COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS));
2467 mutex_unlock(&info->port.mutex);
2465 if (err) { 2468 if (err) {
2466 if ( debug_level >= DEBUG_LEVEL_INFO ) 2469 if ( debug_level >= DEBUG_LEVEL_INFO )
2467 printk( "%s(%d):mgsl_get_params(%s) user buffer copy failed\n", 2470 printk( "%s(%d):mgsl_get_params(%s) user buffer copy failed\n",
@@ -2501,11 +2504,13 @@ static int mgsl_set_params(struct mgsl_struct * info, MGSL_PARAMS __user *new_pa
2501 return -EFAULT; 2504 return -EFAULT;
2502 } 2505 }
2503 2506
2507 mutex_lock(&info->port.mutex);
2504 spin_lock_irqsave(&info->irq_spinlock,flags); 2508 spin_lock_irqsave(&info->irq_spinlock,flags);
2505 memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); 2509 memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS));
2506 spin_unlock_irqrestore(&info->irq_spinlock,flags); 2510 spin_unlock_irqrestore(&info->irq_spinlock,flags);
2507 2511
2508 mgsl_change_params(info); 2512 mgsl_change_params(info);
2513 mutex_unlock(&info->port.mutex);
2509 2514
2510 return 0; 2515 return 0;
2511 2516
@@ -2935,7 +2940,6 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file,
2935 unsigned int cmd, unsigned long arg) 2940 unsigned int cmd, unsigned long arg)
2936{ 2941{
2937 struct mgsl_struct * info = tty->driver_data; 2942 struct mgsl_struct * info = tty->driver_data;
2938 int ret;
2939 2943
2940 if (debug_level >= DEBUG_LEVEL_INFO) 2944 if (debug_level >= DEBUG_LEVEL_INFO)
2941 printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__, 2945 printk("%s(%d):mgsl_ioctl %s cmd=%08X\n", __FILE__,__LINE__,
@@ -2950,10 +2954,7 @@ static int mgsl_ioctl(struct tty_struct *tty, struct file * file,
2950 return -EIO; 2954 return -EIO;
2951 } 2955 }
2952 2956
2953 lock_kernel(); 2957 return mgsl_ioctl_common(info, cmd, arg);
2954 ret = mgsl_ioctl_common(info, cmd, arg);
2955 unlock_kernel();
2956 return ret;
2957} 2958}
2958 2959
2959static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg) 2960static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg)
@@ -3109,12 +3110,14 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
3109 3110
3110 if (tty_port_close_start(&info->port, tty, filp) == 0) 3111 if (tty_port_close_start(&info->port, tty, filp) == 0)
3111 goto cleanup; 3112 goto cleanup;
3112 3113
3114 mutex_lock(&info->port.mutex);
3113 if (info->port.flags & ASYNC_INITIALIZED) 3115 if (info->port.flags & ASYNC_INITIALIZED)
3114 mgsl_wait_until_sent(tty, info->timeout); 3116 mgsl_wait_until_sent(tty, info->timeout);
3115 mgsl_flush_buffer(tty); 3117 mgsl_flush_buffer(tty);
3116 tty_ldisc_flush(tty); 3118 tty_ldisc_flush(tty);
3117 shutdown(info); 3119 shutdown(info);
3120 mutex_unlock(&info->port.mutex);
3118 3121
3119 tty_port_close_end(&info->port, tty); 3122 tty_port_close_end(&info->port, tty);
3120 info->port.tty = NULL; 3123 info->port.tty = NULL;
@@ -3162,7 +3165,6 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout)
3162 * Note: use tight timings here to satisfy the NIST-PCTS. 3165 * Note: use tight timings here to satisfy the NIST-PCTS.
3163 */ 3166 */
3164 3167
3165 lock_kernel();
3166 if ( info->params.data_rate ) { 3168 if ( info->params.data_rate ) {
3167 char_time = info->timeout/(32 * 5); 3169 char_time = info->timeout/(32 * 5);
3168 if (!char_time) 3170 if (!char_time)
@@ -3192,7 +3194,6 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout)
3192 break; 3194 break;
3193 } 3195 }
3194 } 3196 }
3195 unlock_kernel();
3196 3197
3197exit: 3198exit:
3198 if (debug_level >= DEBUG_LEVEL_INFO) 3199 if (debug_level >= DEBUG_LEVEL_INFO)
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 334cf5c8c8b6..3c7ac6a3ff80 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>
@@ -901,8 +900,6 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
901 * Note: use tight timings here to satisfy the NIST-PCTS. 900 * Note: use tight timings here to satisfy the NIST-PCTS.
902 */ 901 */
903 902
904 lock_kernel();
905
906 if (info->params.data_rate) { 903 if (info->params.data_rate) {
907 char_time = info->timeout/(32 * 5); 904 char_time = info->timeout/(32 * 5);
908 if (!char_time) 905 if (!char_time)
@@ -920,8 +917,6 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
920 if (timeout && time_after(jiffies, orig_jiffies + timeout)) 917 if (timeout && time_after(jiffies, orig_jiffies + timeout))
921 break; 918 break;
922 } 919 }
923 unlock_kernel();
924
925exit: 920exit:
926 DBGINFO(("%s wait_until_sent exit\n", info->device_name)); 921 DBGINFO(("%s wait_until_sent exit\n", info->device_name));
927} 922}
@@ -1041,8 +1036,37 @@ static int ioctl(struct tty_struct *tty, struct file *file,
1041 return -EIO; 1036 return -EIO;
1042 } 1037 }
1043 1038
1044 lock_kernel(); 1039 switch (cmd) {
1045 1040 case MGSL_IOCWAITEVENT:
1041 return wait_mgsl_event(info, argp);
1042 case TIOCMIWAIT:
1043 return modem_input_wait(info,(int)arg);
1044 case TIOCGICOUNT:
1045 spin_lock_irqsave(&info->lock,flags);
1046 cnow = info->icount;
1047 spin_unlock_irqrestore(&info->lock,flags);
1048 p_cuser = argp;
1049 if (put_user(cnow.cts, &p_cuser->cts) ||
1050 put_user(cnow.dsr, &p_cuser->dsr) ||
1051 put_user(cnow.rng, &p_cuser->rng) ||
1052 put_user(cnow.dcd, &p_cuser->dcd) ||
1053 put_user(cnow.rx, &p_cuser->rx) ||
1054 put_user(cnow.tx, &p_cuser->tx) ||
1055 put_user(cnow.frame, &p_cuser->frame) ||
1056 put_user(cnow.overrun, &p_cuser->overrun) ||
1057 put_user(cnow.parity, &p_cuser->parity) ||
1058 put_user(cnow.brk, &p_cuser->brk) ||
1059 put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
1060 return -EFAULT;
1061 return 0;
1062 case MGSL_IOCSGPIO:
1063 return set_gpio(info, argp);
1064 case MGSL_IOCGGPIO:
1065 return get_gpio(info, argp);
1066 case MGSL_IOCWAITGPIO:
1067 return wait_gpio(info, argp);
1068 }
1069 mutex_lock(&info->port.mutex);
1046 switch (cmd) { 1070 switch (cmd) {
1047 case MGSL_IOCGPARAMS: 1071 case MGSL_IOCGPARAMS:
1048 ret = get_params(info, argp); 1072 ret = get_params(info, argp);
@@ -1068,50 +1092,16 @@ static int ioctl(struct tty_struct *tty, struct file *file,
1068 case MGSL_IOCGSTATS: 1092 case MGSL_IOCGSTATS:
1069 ret = get_stats(info, argp); 1093 ret = get_stats(info, argp);
1070 break; 1094 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: 1095 case MGSL_IOCGIF:
1078 ret = get_interface(info, argp); 1096 ret = get_interface(info, argp);
1079 break; 1097 break;
1080 case MGSL_IOCSIF: 1098 case MGSL_IOCSIF:
1081 ret = set_interface(info,(int)arg); 1099 ret = set_interface(info,(int)arg);
1082 break; 1100 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: 1101 default:
1112 ret = -ENOIOCTLCMD; 1102 ret = -ENOIOCTLCMD;
1113 } 1103 }
1114 unlock_kernel(); 1104 mutex_unlock(&info->port.mutex);
1115 return ret; 1105 return ret;
1116} 1106}
1117 1107
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 2b18adc4ee19..8da976bd7314 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -52,7 +52,6 @@
52#include <linux/mm.h> 52#include <linux/mm.h>
53#include <linux/seq_file.h> 53#include <linux/seq_file.h>
54#include <linux/slab.h> 54#include <linux/slab.h>
55#include <linux/smp_lock.h>
56#include <linux/netdevice.h> 55#include <linux/netdevice.h>
57#include <linux/vmalloc.h> 56#include <linux/vmalloc.h>
58#include <linux/init.h> 57#include <linux/init.h>
@@ -1062,9 +1061,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
1062 if (sanity_check(info, tty->name, "wait_until_sent")) 1061 if (sanity_check(info, tty->name, "wait_until_sent"))
1063 return; 1062 return;
1064 1063
1065 lock_kernel(); 1064 if (!test_bit(ASYNCB_INITIALIZED, &info->port.flags))
1066
1067 if (!(info->port.flags & ASYNC_INITIALIZED))
1068 goto exit; 1065 goto exit;
1069 1066
1070 orig_jiffies = jiffies; 1067 orig_jiffies = jiffies;
@@ -1094,8 +1091,10 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
1094 break; 1091 break;
1095 } 1092 }
1096 } else { 1093 } else {
1097 //TODO: determine if there is something similar to USC16C32 1094 /*
1098 // TXSTATUS_ALL_SENT status 1095 * TODO: determine if there is something similar to USC16C32
1096 * TXSTATUS_ALL_SENT status
1097 */
1099 while ( info->tx_active && info->tx_enabled) { 1098 while ( info->tx_active && info->tx_enabled) {
1100 msleep_interruptible(jiffies_to_msecs(char_time)); 1099 msleep_interruptible(jiffies_to_msecs(char_time));
1101 if (signal_pending(current)) 1100 if (signal_pending(current))
@@ -1106,7 +1105,6 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
1106 } 1105 }
1107 1106
1108exit: 1107exit:
1109 unlock_kernel();
1110 if (debug_level >= DEBUG_LEVEL_INFO) 1108 if (debug_level >= DEBUG_LEVEL_INFO)
1111 printk("%s(%d):%s wait_until_sent() exit\n", 1109 printk("%s(%d):%s wait_until_sent() exit\n",
1112 __FILE__,__LINE__, info->device_name ); 1110 __FILE__,__LINE__, info->device_name );
@@ -1122,7 +1120,6 @@ static int write_room(struct tty_struct *tty)
1122 if (sanity_check(info, tty->name, "write_room")) 1120 if (sanity_check(info, tty->name, "write_room"))
1123 return 0; 1121 return 0;
1124 1122
1125 lock_kernel();
1126 if (info->params.mode == MGSL_MODE_HDLC) { 1123 if (info->params.mode == MGSL_MODE_HDLC) {
1127 ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; 1124 ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE;
1128 } else { 1125 } else {
@@ -1130,7 +1127,6 @@ static int write_room(struct tty_struct *tty)
1130 if (ret < 0) 1127 if (ret < 0)
1131 ret = 0; 1128 ret = 0;
1132 } 1129 }
1133 unlock_kernel();
1134 1130
1135 if (debug_level >= DEBUG_LEVEL_INFO) 1131 if (debug_level >= DEBUG_LEVEL_INFO)
1136 printk("%s(%d):%s write_room()=%d\n", 1132 printk("%s(%d):%s write_room()=%d\n",
@@ -1251,7 +1247,7 @@ static void tx_release(struct tty_struct *tty)
1251 * 1247 *
1252 * Return Value: 0 if success, otherwise error code 1248 * Return Value: 0 if success, otherwise error code
1253 */ 1249 */
1254static int do_ioctl(struct tty_struct *tty, struct file *file, 1250static int ioctl(struct tty_struct *tty, struct file *file,
1255 unsigned int cmd, unsigned long arg) 1251 unsigned int cmd, unsigned long arg)
1256{ 1252{
1257 SLMP_INFO *info = tty->driver_data; 1253 SLMP_INFO *info = tty->driver_data;
@@ -1341,16 +1337,6 @@ static int do_ioctl(struct tty_struct *tty, struct file *file,
1341 return 0; 1337 return 0;
1342} 1338}
1343 1339
1344static int ioctl(struct tty_struct *tty, struct file *file,
1345 unsigned int cmd, unsigned long arg)
1346{
1347 int ret;
1348 lock_kernel();
1349 ret = do_ioctl(tty, file, cmd, arg);
1350 unlock_kernel();
1351 return ret;
1352}
1353
1354/* 1340/*
1355 * /proc fs routines.... 1341 * /proc fs routines....
1356 */ 1342 */
@@ -2883,7 +2869,9 @@ static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount)
2883 if (!user_icount) { 2869 if (!user_icount) {
2884 memset(&info->icount, 0, sizeof(info->icount)); 2870 memset(&info->icount, 0, sizeof(info->icount));
2885 } else { 2871 } else {
2872 mutex_lock(&info->port.mutex);
2886 COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); 2873 COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
2874 mutex_unlock(&info->port.mutex);
2887 if (err) 2875 if (err)
2888 return -EFAULT; 2876 return -EFAULT;
2889 } 2877 }
@@ -2898,7 +2886,9 @@ static int get_params(SLMP_INFO * info, MGSL_PARAMS __user *user_params)
2898 printk("%s(%d):%s get_params()\n", 2886 printk("%s(%d):%s get_params()\n",
2899 __FILE__,__LINE__, info->device_name); 2887 __FILE__,__LINE__, info->device_name);
2900 2888
2889 mutex_lock(&info->port.mutex);
2901 COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); 2890 COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS));
2891 mutex_unlock(&info->port.mutex);
2902 if (err) { 2892 if (err) {
2903 if ( debug_level >= DEBUG_LEVEL_INFO ) 2893 if ( debug_level >= DEBUG_LEVEL_INFO )
2904 printk( "%s(%d):%s get_params() user buffer copy failed\n", 2894 printk( "%s(%d):%s get_params() user buffer copy failed\n",
@@ -2926,11 +2916,13 @@ static int set_params(SLMP_INFO * info, MGSL_PARAMS __user *new_params)
2926 return -EFAULT; 2916 return -EFAULT;
2927 } 2917 }
2928 2918
2919 mutex_lock(&info->port.mutex);
2929 spin_lock_irqsave(&info->lock,flags); 2920 spin_lock_irqsave(&info->lock,flags);
2930 memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); 2921 memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS));
2931 spin_unlock_irqrestore(&info->lock,flags); 2922 spin_unlock_irqrestore(&info->lock,flags);
2932 2923
2933 change_params(info); 2924 change_params(info);
2925 mutex_unlock(&info->port.mutex);
2934 2926
2935 return 0; 2927 return 0;
2936} 2928}