diff options
Diffstat (limited to 'drivers/char/synclinkmp.c')
-rw-r--r-- | drivers/char/synclinkmp.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 2b18adc4ee19..e56caf7d82aa 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> |
@@ -813,13 +812,15 @@ static void close(struct tty_struct *tty, struct file *filp) | |||
813 | 812 | ||
814 | if (tty_port_close_start(&info->port, tty, filp) == 0) | 813 | if (tty_port_close_start(&info->port, tty, filp) == 0) |
815 | goto cleanup; | 814 | goto cleanup; |
816 | 815 | ||
816 | mutex_lock(&info->port.mutex); | ||
817 | if (info->port.flags & ASYNC_INITIALIZED) | 817 | if (info->port.flags & ASYNC_INITIALIZED) |
818 | wait_until_sent(tty, info->timeout); | 818 | wait_until_sent(tty, info->timeout); |
819 | 819 | ||
820 | flush_buffer(tty); | 820 | flush_buffer(tty); |
821 | tty_ldisc_flush(tty); | 821 | tty_ldisc_flush(tty); |
822 | shutdown(info); | 822 | shutdown(info); |
823 | mutex_unlock(&info->port.mutex); | ||
823 | 824 | ||
824 | tty_port_close_end(&info->port, tty); | 825 | tty_port_close_end(&info->port, tty); |
825 | info->port.tty = NULL; | 826 | info->port.tty = NULL; |
@@ -835,6 +836,7 @@ cleanup: | |||
835 | static void hangup(struct tty_struct *tty) | 836 | static void hangup(struct tty_struct *tty) |
836 | { | 837 | { |
837 | SLMP_INFO *info = tty->driver_data; | 838 | SLMP_INFO *info = tty->driver_data; |
839 | unsigned long flags; | ||
838 | 840 | ||
839 | if (debug_level >= DEBUG_LEVEL_INFO) | 841 | if (debug_level >= DEBUG_LEVEL_INFO) |
840 | printk("%s(%d):%s hangup()\n", | 842 | printk("%s(%d):%s hangup()\n", |
@@ -843,12 +845,16 @@ static void hangup(struct tty_struct *tty) | |||
843 | if (sanity_check(info, tty->name, "hangup")) | 845 | if (sanity_check(info, tty->name, "hangup")) |
844 | return; | 846 | return; |
845 | 847 | ||
848 | mutex_lock(&info->port.mutex); | ||
846 | flush_buffer(tty); | 849 | flush_buffer(tty); |
847 | shutdown(info); | 850 | shutdown(info); |
848 | 851 | ||
852 | spin_lock_irqsave(&info->port.lock, flags); | ||
849 | info->port.count = 0; | 853 | info->port.count = 0; |
850 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; | 854 | info->port.flags &= ~ASYNC_NORMAL_ACTIVE; |
851 | info->port.tty = NULL; | 855 | info->port.tty = NULL; |
856 | spin_unlock_irqrestore(&info->port.lock, flags); | ||
857 | mutex_unlock(&info->port.mutex); | ||
852 | 858 | ||
853 | wake_up_interruptible(&info->port.open_wait); | 859 | wake_up_interruptible(&info->port.open_wait); |
854 | } | 860 | } |
@@ -1062,9 +1068,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
1062 | if (sanity_check(info, tty->name, "wait_until_sent")) | 1068 | if (sanity_check(info, tty->name, "wait_until_sent")) |
1063 | return; | 1069 | return; |
1064 | 1070 | ||
1065 | lock_kernel(); | 1071 | if (!test_bit(ASYNCB_INITIALIZED, &info->port.flags)) |
1066 | |||
1067 | if (!(info->port.flags & ASYNC_INITIALIZED)) | ||
1068 | goto exit; | 1072 | goto exit; |
1069 | 1073 | ||
1070 | orig_jiffies = jiffies; | 1074 | orig_jiffies = jiffies; |
@@ -1094,8 +1098,10 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
1094 | break; | 1098 | break; |
1095 | } | 1099 | } |
1096 | } else { | 1100 | } else { |
1097 | //TODO: determine if there is something similar to USC16C32 | 1101 | /* |
1098 | // TXSTATUS_ALL_SENT status | 1102 | * TODO: determine if there is something similar to USC16C32 |
1103 | * TXSTATUS_ALL_SENT status | ||
1104 | */ | ||
1099 | while ( info->tx_active && info->tx_enabled) { | 1105 | while ( info->tx_active && info->tx_enabled) { |
1100 | msleep_interruptible(jiffies_to_msecs(char_time)); | 1106 | msleep_interruptible(jiffies_to_msecs(char_time)); |
1101 | if (signal_pending(current)) | 1107 | if (signal_pending(current)) |
@@ -1106,7 +1112,6 @@ static void wait_until_sent(struct tty_struct *tty, int timeout) | |||
1106 | } | 1112 | } |
1107 | 1113 | ||
1108 | exit: | 1114 | exit: |
1109 | unlock_kernel(); | ||
1110 | if (debug_level >= DEBUG_LEVEL_INFO) | 1115 | if (debug_level >= DEBUG_LEVEL_INFO) |
1111 | printk("%s(%d):%s wait_until_sent() exit\n", | 1116 | printk("%s(%d):%s wait_until_sent() exit\n", |
1112 | __FILE__,__LINE__, info->device_name ); | 1117 | __FILE__,__LINE__, info->device_name ); |
@@ -1122,7 +1127,6 @@ static int write_room(struct tty_struct *tty) | |||
1122 | if (sanity_check(info, tty->name, "write_room")) | 1127 | if (sanity_check(info, tty->name, "write_room")) |
1123 | return 0; | 1128 | return 0; |
1124 | 1129 | ||
1125 | lock_kernel(); | ||
1126 | if (info->params.mode == MGSL_MODE_HDLC) { | 1130 | if (info->params.mode == MGSL_MODE_HDLC) { |
1127 | ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; | 1131 | ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; |
1128 | } else { | 1132 | } else { |
@@ -1130,7 +1134,6 @@ static int write_room(struct tty_struct *tty) | |||
1130 | if (ret < 0) | 1134 | if (ret < 0) |
1131 | ret = 0; | 1135 | ret = 0; |
1132 | } | 1136 | } |
1133 | unlock_kernel(); | ||
1134 | 1137 | ||
1135 | if (debug_level >= DEBUG_LEVEL_INFO) | 1138 | if (debug_level >= DEBUG_LEVEL_INFO) |
1136 | printk("%s(%d):%s write_room()=%d\n", | 1139 | printk("%s(%d):%s write_room()=%d\n", |
@@ -1251,7 +1254,7 @@ static void tx_release(struct tty_struct *tty) | |||
1251 | * | 1254 | * |
1252 | * Return Value: 0 if success, otherwise error code | 1255 | * Return Value: 0 if success, otherwise error code |
1253 | */ | 1256 | */ |
1254 | static int do_ioctl(struct tty_struct *tty, struct file *file, | 1257 | static int ioctl(struct tty_struct *tty, struct file *file, |
1255 | unsigned int cmd, unsigned long arg) | 1258 | unsigned int cmd, unsigned long arg) |
1256 | { | 1259 | { |
1257 | SLMP_INFO *info = tty->driver_data; | 1260 | SLMP_INFO *info = tty->driver_data; |
@@ -1341,16 +1344,6 @@ static int do_ioctl(struct tty_struct *tty, struct file *file, | |||
1341 | return 0; | 1344 | return 0; |
1342 | } | 1345 | } |
1343 | 1346 | ||
1344 | static 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 | /* | 1347 | /* |
1355 | * /proc fs routines.... | 1348 | * /proc fs routines.... |
1356 | */ | 1349 | */ |
@@ -2883,7 +2876,9 @@ static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount) | |||
2883 | if (!user_icount) { | 2876 | if (!user_icount) { |
2884 | memset(&info->icount, 0, sizeof(info->icount)); | 2877 | memset(&info->icount, 0, sizeof(info->icount)); |
2885 | } else { | 2878 | } else { |
2879 | mutex_lock(&info->port.mutex); | ||
2886 | COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); | 2880 | COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount)); |
2881 | mutex_unlock(&info->port.mutex); | ||
2887 | if (err) | 2882 | if (err) |
2888 | return -EFAULT; | 2883 | return -EFAULT; |
2889 | } | 2884 | } |
@@ -2898,7 +2893,9 @@ static int get_params(SLMP_INFO * info, MGSL_PARAMS __user *user_params) | |||
2898 | printk("%s(%d):%s get_params()\n", | 2893 | printk("%s(%d):%s get_params()\n", |
2899 | __FILE__,__LINE__, info->device_name); | 2894 | __FILE__,__LINE__, info->device_name); |
2900 | 2895 | ||
2896 | mutex_lock(&info->port.mutex); | ||
2901 | COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); | 2897 | COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS)); |
2898 | mutex_unlock(&info->port.mutex); | ||
2902 | if (err) { | 2899 | if (err) { |
2903 | if ( debug_level >= DEBUG_LEVEL_INFO ) | 2900 | if ( debug_level >= DEBUG_LEVEL_INFO ) |
2904 | printk( "%s(%d):%s get_params() user buffer copy failed\n", | 2901 | printk( "%s(%d):%s get_params() user buffer copy failed\n", |
@@ -2926,11 +2923,13 @@ static int set_params(SLMP_INFO * info, MGSL_PARAMS __user *new_params) | |||
2926 | return -EFAULT; | 2923 | return -EFAULT; |
2927 | } | 2924 | } |
2928 | 2925 | ||
2926 | mutex_lock(&info->port.mutex); | ||
2929 | spin_lock_irqsave(&info->lock,flags); | 2927 | spin_lock_irqsave(&info->lock,flags); |
2930 | memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); | 2928 | memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS)); |
2931 | spin_unlock_irqrestore(&info->lock,flags); | 2929 | spin_unlock_irqrestore(&info->lock,flags); |
2932 | 2930 | ||
2933 | change_params(info); | 2931 | change_params(info); |
2932 | mutex_unlock(&info->port.mutex); | ||
2934 | 2933 | ||
2935 | return 0; | 2934 | return 0; |
2936 | } | 2935 | } |
@@ -3366,7 +3365,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3366 | printk("%s(%d):%s block_til_ready() count=%d\n", | 3365 | printk("%s(%d):%s block_til_ready() count=%d\n", |
3367 | __FILE__,__LINE__, tty->driver->name, port->count ); | 3366 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3368 | 3367 | ||
3368 | tty_unlock(); | ||
3369 | schedule(); | 3369 | schedule(); |
3370 | tty_lock(); | ||
3370 | } | 3371 | } |
3371 | 3372 | ||
3372 | set_current_state(TASK_RUNNING); | 3373 | set_current_state(TASK_RUNNING); |