aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/n_r3964.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-04-30 03:53:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:40 -0400
commit04f378b198da233ca0aca341b113dc6579d46123 (patch)
tree696e7bd401125cee71ecaa2047c4273f38732554 /drivers/char/n_r3964.c
parente52384426064bca0669a954736206adca7595d48 (diff)
tty: BKL pushdown
- Push the BKL down into the line disciplines - Switch the tty layer to unlocked_ioctl - Introduce a new ctrl_lock spin lock for the control bits - Eliminate much of the lock_kernel use in n_tty - Prepare to (but don't yet) call the drivers with the lock dropped on the paths that historically held the lock BKL now primarily protects open/close/ldisc change in the tty layer [jirislaby@gmail.com: a couple of fixes] Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/n_r3964.c')
-rw-r--r--drivers/char/n_r3964.c16
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