diff options
Diffstat (limited to 'drivers/char/n_r3964.c')
-rw-r--r-- | drivers/char/n_r3964.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index 6b918b80f73e..3f6486e9f1ec 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -1075,12 +1075,15 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1075 | 1075 | ||
1076 | TRACE_L("read()"); | 1076 | TRACE_L("read()"); |
1077 | 1077 | ||
1078 | lock_kernel(); | ||
1079 | |||
1078 | pClient = findClient(pInfo, task_pid(current)); | 1080 | pClient = findClient(pInfo, task_pid(current)); |
1079 | if (pClient) { | 1081 | if (pClient) { |
1080 | pMsg = remove_msg(pInfo, pClient); | 1082 | pMsg = remove_msg(pInfo, pClient); |
1081 | if (pMsg == NULL) { | 1083 | if (pMsg == NULL) { |
1082 | /* no messages available. */ | 1084 | /* no messages available. */ |
1083 | if (file->f_flags & O_NONBLOCK) { | 1085 | if (file->f_flags & O_NONBLOCK) { |
1086 | unlock_kernel(); | ||
1084 | return -EAGAIN; | 1087 | return -EAGAIN; |
1085 | } | 1088 | } |
1086 | /* block until there is a message: */ | 1089 | /* block until there is a message: */ |
@@ -1090,8 +1093,10 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1090 | 1093 | ||
1091 | /* If we still haven't got a message, we must have been signalled */ | 1094 | /* If we still haven't got a message, we must have been signalled */ |
1092 | 1095 | ||
1093 | if (!pMsg) | 1096 | if (!pMsg) { |
1097 | unlock_kernel(); | ||
1094 | return -EINTR; | 1098 | return -EINTR; |
1099 | } | ||
1095 | 1100 | ||
1096 | /* deliver msg to client process: */ | 1101 | /* deliver msg to client process: */ |
1097 | theMsg.msg_id = pMsg->msg_id; | 1102 | theMsg.msg_id = pMsg->msg_id; |
@@ -1102,12 +1107,15 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1102 | kfree(pMsg); | 1107 | kfree(pMsg); |
1103 | TRACE_M("r3964_read - msg kfree %p", pMsg); | 1108 | TRACE_M("r3964_read - msg kfree %p", pMsg); |
1104 | 1109 | ||
1105 | if (copy_to_user(buf, &theMsg, count)) | 1110 | if (copy_to_user(buf, &theMsg, count)) { |
1111 | unlock_kernel(); | ||
1106 | return -EFAULT; | 1112 | return -EFAULT; |
1113 | } | ||
1107 | 1114 | ||
1108 | TRACE_PS("read - return %d", count); | 1115 | TRACE_PS("read - return %d", count); |
1109 | return count; | 1116 | return count; |
1110 | } | 1117 | } |
1118 | unlock_kernel(); | ||
1111 | return -EPERM; | 1119 | return -EPERM; |
1112 | } | 1120 | } |
1113 | 1121 | ||
@@ -1156,6 +1164,8 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, | |||
1156 | pHeader->locks = 0; | 1164 | pHeader->locks = 0; |
1157 | pHeader->owner = NULL; | 1165 | pHeader->owner = NULL; |
1158 | 1166 | ||
1167 | lock_kernel(); | ||
1168 | |||
1159 | pClient = findClient(pInfo, task_pid(current)); | 1169 | pClient = findClient(pInfo, task_pid(current)); |
1160 | if (pClient) { | 1170 | if (pClient) { |
1161 | pHeader->owner = pClient; | 1171 | pHeader->owner = pClient; |
@@ -1173,6 +1183,8 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, | |||
1173 | add_tx_queue(pInfo, pHeader); | 1183 | add_tx_queue(pInfo, pHeader); |
1174 | trigger_transmit(pInfo); | 1184 | trigger_transmit(pInfo); |
1175 | 1185 | ||
1186 | unlock_kernel(); | ||
1187 | |||
1176 | return 0; | 1188 | return 0; |
1177 | } | 1189 | } |
1178 | 1190 | ||