aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2009-06-22 13:42:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-22 14:32:23 -0400
commiteca41044268887838fa122aa24475df8f23d614c (patch)
tree9cf22d5b96037273f6aa30fb9eb61ff4f9f04b7b /drivers/char
parent52e3632ea603ef92757d5d0dedcd9fc8643445e3 (diff)
n_r3964: fix lock imbalance
There is omitted BKunL in r3964_read. Centralize the paths to one point with one unlock. Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Cc: stable@kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/n_r3964.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index d2e93e343226..2e99158ebb8a 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -1062,7 +1062,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1062 struct r3964_client_info *pClient; 1062 struct r3964_client_info *pClient;
1063 struct r3964_message *pMsg; 1063 struct r3964_message *pMsg;
1064 struct r3964_client_message theMsg; 1064 struct r3964_client_message theMsg;
1065 int count; 1065 int ret;
1066 1066
1067 TRACE_L("read()"); 1067 TRACE_L("read()");
1068 1068
@@ -1074,8 +1074,8 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1074 if (pMsg == NULL) { 1074 if (pMsg == NULL) {
1075 /* no messages available. */ 1075 /* no messages available. */
1076 if (file->f_flags & O_NONBLOCK) { 1076 if (file->f_flags & O_NONBLOCK) {
1077 unlock_kernel(); 1077 ret = -EAGAIN;
1078 return -EAGAIN; 1078 goto unlock;
1079 } 1079 }
1080 /* block until there is a message: */ 1080 /* block until there is a message: */
1081 wait_event_interruptible(pInfo->read_wait, 1081 wait_event_interruptible(pInfo->read_wait,
@@ -1085,29 +1085,31 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1085 /* If we still haven't got a message, we must have been signalled */ 1085 /* If we still haven't got a message, we must have been signalled */
1086 1086
1087 if (!pMsg) { 1087 if (!pMsg) {
1088 unlock_kernel(); 1088 ret = -EINTR;
1089 return -EINTR; 1089 goto unlock;
1090 } 1090 }
1091 1091
1092 /* deliver msg to client process: */ 1092 /* deliver msg to client process: */
1093 theMsg.msg_id = pMsg->msg_id; 1093 theMsg.msg_id = pMsg->msg_id;
1094 theMsg.arg = pMsg->arg; 1094 theMsg.arg = pMsg->arg;
1095 theMsg.error_code = pMsg->error_code; 1095 theMsg.error_code = pMsg->error_code;
1096 count = sizeof(struct r3964_client_message); 1096 ret = sizeof(struct r3964_client_message);
1097 1097
1098 kfree(pMsg); 1098 kfree(pMsg);
1099 TRACE_M("r3964_read - msg kfree %p", pMsg); 1099 TRACE_M("r3964_read - msg kfree %p", pMsg);
1100 1100
1101 if (copy_to_user(buf, &theMsg, count)) { 1101 if (copy_to_user(buf, &theMsg, ret)) {
1102 unlock_kernel(); 1102 ret = -EFAULT;
1103 return -EFAULT; 1103 goto unlock;
1104 } 1104 }
1105 1105
1106 TRACE_PS("read - return %d", count); 1106 TRACE_PS("read - return %d", ret);
1107 return count; 1107 goto unlock;
1108 } 1108 }
1109 ret = -EPERM;
1110unlock:
1109 unlock_kernel(); 1111 unlock_kernel();
1110 return -EPERM; 1112 return ret;
1111} 1113}
1112 1114
1113static ssize_t r3964_write(struct tty_struct *tty, struct file *file, 1115static ssize_t r3964_write(struct tty_struct *tty, struct file *file,