diff options
Diffstat (limited to 'fs/coda/psdev.c')
-rw-r--r-- | fs/coda/psdev.c | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 66b9cf79c5ba..62647a8595e4 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/poll.h> | 35 | #include <linux/poll.h> |
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/list.h> | 37 | #include <linux/list.h> |
38 | #include <linux/smp_lock.h> | 38 | #include <linux/mutex.h> |
39 | #include <linux/device.h> | 39 | #include <linux/device.h> |
40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
41 | #include <asm/system.h> | 41 | #include <asm/system.h> |
@@ -67,8 +67,10 @@ static unsigned int coda_psdev_poll(struct file *file, poll_table * wait) | |||
67 | unsigned int mask = POLLOUT | POLLWRNORM; | 67 | unsigned int mask = POLLOUT | POLLWRNORM; |
68 | 68 | ||
69 | poll_wait(file, &vcp->vc_waitq, wait); | 69 | poll_wait(file, &vcp->vc_waitq, wait); |
70 | mutex_lock(&vcp->vc_mutex); | ||
70 | if (!list_empty(&vcp->vc_pending)) | 71 | if (!list_empty(&vcp->vc_pending)) |
71 | mask |= POLLIN | POLLRDNORM; | 72 | mask |= POLLIN | POLLRDNORM; |
73 | mutex_unlock(&vcp->vc_mutex); | ||
72 | 74 | ||
73 | return mask; | 75 | return mask; |
74 | } | 76 | } |
@@ -108,16 +110,9 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, | |||
108 | return -EFAULT; | 110 | return -EFAULT; |
109 | 111 | ||
110 | if (DOWNCALL(hdr.opcode)) { | 112 | if (DOWNCALL(hdr.opcode)) { |
111 | struct super_block *sb = NULL; | 113 | union outputArgs *dcbuf; |
112 | union outputArgs *dcbuf; | ||
113 | int size = sizeof(*dcbuf); | 114 | int size = sizeof(*dcbuf); |
114 | 115 | ||
115 | sb = vcp->vc_sb; | ||
116 | if ( !sb ) { | ||
117 | count = nbytes; | ||
118 | goto out; | ||
119 | } | ||
120 | |||
121 | if ( nbytes < sizeof(struct coda_out_hdr) ) { | 116 | if ( nbytes < sizeof(struct coda_out_hdr) ) { |
122 | printk("coda_downcall opc %d uniq %d, not enough!\n", | 117 | printk("coda_downcall opc %d uniq %d, not enough!\n", |
123 | hdr.opcode, hdr.unique); | 118 | hdr.opcode, hdr.unique); |
@@ -137,9 +132,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, | |||
137 | } | 132 | } |
138 | 133 | ||
139 | /* what downcall errors does Venus handle ? */ | 134 | /* what downcall errors does Venus handle ? */ |
140 | lock_kernel(); | 135 | error = coda_downcall(vcp, hdr.opcode, dcbuf); |
141 | error = coda_downcall(hdr.opcode, dcbuf, sb); | ||
142 | unlock_kernel(); | ||
143 | 136 | ||
144 | CODA_FREE(dcbuf, nbytes); | 137 | CODA_FREE(dcbuf, nbytes); |
145 | if (error) { | 138 | if (error) { |
@@ -152,7 +145,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, | |||
152 | } | 145 | } |
153 | 146 | ||
154 | /* Look for the message on the processing queue. */ | 147 | /* Look for the message on the processing queue. */ |
155 | lock_kernel(); | 148 | mutex_lock(&vcp->vc_mutex); |
156 | list_for_each(lh, &vcp->vc_processing) { | 149 | list_for_each(lh, &vcp->vc_processing) { |
157 | tmp = list_entry(lh, struct upc_req , uc_chain); | 150 | tmp = list_entry(lh, struct upc_req , uc_chain); |
158 | if (tmp->uc_unique == hdr.unique) { | 151 | if (tmp->uc_unique == hdr.unique) { |
@@ -161,7 +154,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, | |||
161 | break; | 154 | break; |
162 | } | 155 | } |
163 | } | 156 | } |
164 | unlock_kernel(); | 157 | mutex_unlock(&vcp->vc_mutex); |
165 | 158 | ||
166 | if (!req) { | 159 | if (!req) { |
167 | printk("psdev_write: msg (%d, %d) not found\n", | 160 | printk("psdev_write: msg (%d, %d) not found\n", |
@@ -177,15 +170,15 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, | |||
177 | nbytes = req->uc_outSize; /* don't have more space! */ | 170 | nbytes = req->uc_outSize; /* don't have more space! */ |
178 | } | 171 | } |
179 | if (copy_from_user(req->uc_data, buf, nbytes)) { | 172 | if (copy_from_user(req->uc_data, buf, nbytes)) { |
180 | req->uc_flags |= REQ_ABORT; | 173 | req->uc_flags |= CODA_REQ_ABORT; |
181 | wake_up(&req->uc_sleep); | 174 | wake_up(&req->uc_sleep); |
182 | retval = -EFAULT; | 175 | retval = -EFAULT; |
183 | goto out; | 176 | goto out; |
184 | } | 177 | } |
185 | 178 | ||
186 | /* adjust outsize. is this useful ?? */ | 179 | /* adjust outsize. is this useful ?? */ |
187 | req->uc_outSize = nbytes; | 180 | req->uc_outSize = nbytes; |
188 | req->uc_flags |= REQ_WRITE; | 181 | req->uc_flags |= CODA_REQ_WRITE; |
189 | count = nbytes; | 182 | count = nbytes; |
190 | 183 | ||
191 | /* Convert filedescriptor into a file handle */ | 184 | /* Convert filedescriptor into a file handle */ |
@@ -216,7 +209,7 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf, | |||
216 | if (nbytes == 0) | 209 | if (nbytes == 0) |
217 | return 0; | 210 | return 0; |
218 | 211 | ||
219 | lock_kernel(); | 212 | mutex_lock(&vcp->vc_mutex); |
220 | 213 | ||
221 | add_wait_queue(&vcp->vc_waitq, &wait); | 214 | add_wait_queue(&vcp->vc_waitq, &wait); |
222 | set_current_state(TASK_INTERRUPTIBLE); | 215 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -230,7 +223,9 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf, | |||
230 | retval = -ERESTARTSYS; | 223 | retval = -ERESTARTSYS; |
231 | break; | 224 | break; |
232 | } | 225 | } |
226 | mutex_unlock(&vcp->vc_mutex); | ||
233 | schedule(); | 227 | schedule(); |
228 | mutex_lock(&vcp->vc_mutex); | ||
234 | } | 229 | } |
235 | 230 | ||
236 | set_current_state(TASK_RUNNING); | 231 | set_current_state(TASK_RUNNING); |
@@ -254,8 +249,8 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf, | |||
254 | retval = -EFAULT; | 249 | retval = -EFAULT; |
255 | 250 | ||
256 | /* If request was not a signal, enqueue and don't free */ | 251 | /* If request was not a signal, enqueue and don't free */ |
257 | if (!(req->uc_flags & REQ_ASYNC)) { | 252 | if (!(req->uc_flags & CODA_REQ_ASYNC)) { |
258 | req->uc_flags |= REQ_READ; | 253 | req->uc_flags |= CODA_REQ_READ; |
259 | list_add_tail(&(req->uc_chain), &vcp->vc_processing); | 254 | list_add_tail(&(req->uc_chain), &vcp->vc_processing); |
260 | goto out; | 255 | goto out; |
261 | } | 256 | } |
@@ -263,7 +258,7 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf, | |||
263 | CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); | 258 | CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); |
264 | kfree(req); | 259 | kfree(req); |
265 | out: | 260 | out: |
266 | unlock_kernel(); | 261 | mutex_unlock(&vcp->vc_mutex); |
267 | return (count ? count : retval); | 262 | return (count ? count : retval); |
268 | } | 263 | } |
269 | 264 | ||
@@ -276,10 +271,10 @@ static int coda_psdev_open(struct inode * inode, struct file * file) | |||
276 | if (idx < 0 || idx >= MAX_CODADEVS) | 271 | if (idx < 0 || idx >= MAX_CODADEVS) |
277 | return -ENODEV; | 272 | return -ENODEV; |
278 | 273 | ||
279 | lock_kernel(); | ||
280 | |||
281 | err = -EBUSY; | 274 | err = -EBUSY; |
282 | vcp = &coda_comms[idx]; | 275 | vcp = &coda_comms[idx]; |
276 | mutex_lock(&vcp->vc_mutex); | ||
277 | |||
283 | if (!vcp->vc_inuse) { | 278 | if (!vcp->vc_inuse) { |
284 | vcp->vc_inuse++; | 279 | vcp->vc_inuse++; |
285 | 280 | ||
@@ -293,7 +288,7 @@ static int coda_psdev_open(struct inode * inode, struct file * file) | |||
293 | err = 0; | 288 | err = 0; |
294 | } | 289 | } |
295 | 290 | ||
296 | unlock_kernel(); | 291 | mutex_unlock(&vcp->vc_mutex); |
297 | return err; | 292 | return err; |
298 | } | 293 | } |
299 | 294 | ||
@@ -308,32 +303,32 @@ static int coda_psdev_release(struct inode * inode, struct file * file) | |||
308 | return -1; | 303 | return -1; |
309 | } | 304 | } |
310 | 305 | ||
311 | lock_kernel(); | 306 | mutex_lock(&vcp->vc_mutex); |
312 | 307 | ||
313 | /* Wakeup clients so they can return. */ | 308 | /* Wakeup clients so they can return. */ |
314 | list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) { | 309 | list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) { |
315 | list_del(&req->uc_chain); | 310 | list_del(&req->uc_chain); |
316 | 311 | ||
317 | /* Async requests need to be freed here */ | 312 | /* Async requests need to be freed here */ |
318 | if (req->uc_flags & REQ_ASYNC) { | 313 | if (req->uc_flags & CODA_REQ_ASYNC) { |
319 | CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); | 314 | CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); |
320 | kfree(req); | 315 | kfree(req); |
321 | continue; | 316 | continue; |
322 | } | 317 | } |
323 | req->uc_flags |= REQ_ABORT; | 318 | req->uc_flags |= CODA_REQ_ABORT; |
324 | wake_up(&req->uc_sleep); | 319 | wake_up(&req->uc_sleep); |
325 | } | 320 | } |
326 | 321 | ||
327 | list_for_each_entry_safe(req, tmp, &vcp->vc_processing, uc_chain) { | 322 | list_for_each_entry_safe(req, tmp, &vcp->vc_processing, uc_chain) { |
328 | list_del(&req->uc_chain); | 323 | list_del(&req->uc_chain); |
329 | 324 | ||
330 | req->uc_flags |= REQ_ABORT; | 325 | req->uc_flags |= CODA_REQ_ABORT; |
331 | wake_up(&req->uc_sleep); | 326 | wake_up(&req->uc_sleep); |
332 | } | 327 | } |
333 | 328 | ||
334 | file->private_data = NULL; | 329 | file->private_data = NULL; |
335 | vcp->vc_inuse--; | 330 | vcp->vc_inuse--; |
336 | unlock_kernel(); | 331 | mutex_unlock(&vcp->vc_mutex); |
337 | return 0; | 332 | return 0; |
338 | } | 333 | } |
339 | 334 | ||
@@ -346,6 +341,7 @@ static const struct file_operations coda_psdev_fops = { | |||
346 | .unlocked_ioctl = coda_psdev_ioctl, | 341 | .unlocked_ioctl = coda_psdev_ioctl, |
347 | .open = coda_psdev_open, | 342 | .open = coda_psdev_open, |
348 | .release = coda_psdev_release, | 343 | .release = coda_psdev_release, |
344 | .llseek = noop_llseek, | ||
349 | }; | 345 | }; |
350 | 346 | ||
351 | static int init_coda_psdev(void) | 347 | static int init_coda_psdev(void) |
@@ -361,9 +357,11 @@ static int init_coda_psdev(void) | |||
361 | err = PTR_ERR(coda_psdev_class); | 357 | err = PTR_ERR(coda_psdev_class); |
362 | goto out_chrdev; | 358 | goto out_chrdev; |
363 | } | 359 | } |
364 | for (i = 0; i < MAX_CODADEVS; i++) | 360 | for (i = 0; i < MAX_CODADEVS; i++) { |
361 | mutex_init(&(&coda_comms[i])->vc_mutex); | ||
365 | device_create(coda_psdev_class, NULL, | 362 | device_create(coda_psdev_class, NULL, |
366 | MKDEV(CODA_PSDEV_MAJOR, i), NULL, "cfs%d", i); | 363 | MKDEV(CODA_PSDEV_MAJOR, i), NULL, "cfs%d", i); |
364 | } | ||
367 | coda_sysctl_init(); | 365 | coda_sysctl_init(); |
368 | goto out; | 366 | goto out; |
369 | 367 | ||