aboutsummaryrefslogtreecommitdiffstats
path: root/fs/coda/psdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/coda/psdev.c')
-rw-r--r--fs/coda/psdev.c61
1 files changed, 30 insertions, 31 deletions
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 09382d47a4e1..6818c20372ca 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -272,56 +272,51 @@ out:
272 272
273static int coda_psdev_open(struct inode * inode, struct file * file) 273static int coda_psdev_open(struct inode * inode, struct file * file)
274{ 274{
275 struct venus_comm *vcp; 275 struct venus_comm *vcp;
276 int idx; 276 int idx, err;
277 277
278 lock_kernel();
279 idx = iminor(inode); 278 idx = iminor(inode);
280 if(idx >= MAX_CODADEVS) { 279 if (idx < 0 || idx >= MAX_CODADEVS)
281 unlock_kernel();
282 return -ENODEV; 280 return -ENODEV;
283 }
284 281
282 lock_kernel();
283
284 err = -EBUSY;
285 vcp = &coda_comms[idx]; 285 vcp = &coda_comms[idx];
286 if(vcp->vc_inuse) { 286 if (!vcp->vc_inuse) {
287 unlock_kernel(); 287 vcp->vc_inuse++;
288 return -EBUSY; 288
289 }
290
291 if (!vcp->vc_inuse++) {
292 INIT_LIST_HEAD(&vcp->vc_pending); 289 INIT_LIST_HEAD(&vcp->vc_pending);
293 INIT_LIST_HEAD(&vcp->vc_processing); 290 INIT_LIST_HEAD(&vcp->vc_processing);
294 init_waitqueue_head(&vcp->vc_waitq); 291 init_waitqueue_head(&vcp->vc_waitq);
295 vcp->vc_sb = NULL; 292 vcp->vc_sb = NULL;
296 vcp->vc_seq = 0; 293 vcp->vc_seq = 0;
294
295 file->private_data = vcp;
296 err = 0;
297 } 297 }
298
299 file->private_data = vcp;
300 298
301 unlock_kernel(); 299 unlock_kernel();
302 return 0; 300 return err;
303} 301}
304 302
305 303
306static int coda_psdev_release(struct inode * inode, struct file * file) 304static int coda_psdev_release(struct inode * inode, struct file * file)
307{ 305{
308 struct venus_comm *vcp = (struct venus_comm *) file->private_data; 306 struct venus_comm *vcp = (struct venus_comm *) file->private_data;
309 struct upc_req *req, *tmp; 307 struct upc_req *req, *tmp;
310 308
311 lock_kernel(); 309 if (!vcp || !vcp->vc_inuse ) {
312 if ( !vcp->vc_inuse ) {
313 unlock_kernel();
314 printk("psdev_release: Not open.\n"); 310 printk("psdev_release: Not open.\n");
315 return -1; 311 return -1;
316 } 312 }
317 313
318 if (--vcp->vc_inuse) { 314 lock_kernel();
319 unlock_kernel(); 315
320 return 0; 316 /* Wakeup clients so they can return. */
321 }
322
323 /* Wakeup clients so they can return. */
324 list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) { 317 list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) {
318 list_del(&req->uc_chain);
319
325 /* Async requests need to be freed here */ 320 /* Async requests need to be freed here */
326 if (req->uc_flags & REQ_ASYNC) { 321 if (req->uc_flags & REQ_ASYNC) {
327 CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); 322 CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));
@@ -330,13 +325,17 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
330 } 325 }
331 req->uc_flags |= REQ_ABORT; 326 req->uc_flags |= REQ_ABORT;
332 wake_up(&req->uc_sleep); 327 wake_up(&req->uc_sleep);
333 } 328 }
334 329
335 list_for_each_entry(req, &vcp->vc_processing, uc_chain) { 330 list_for_each_entry_safe(req, tmp, &vcp->vc_processing, uc_chain) {
331 list_del(&req->uc_chain);
332
336 req->uc_flags |= REQ_ABORT; 333 req->uc_flags |= REQ_ABORT;
337 wake_up(&req->uc_sleep); 334 wake_up(&req->uc_sleep);
338 } 335 }
339 336
337 file->private_data = NULL;
338 vcp->vc_inuse--;
340 unlock_kernel(); 339 unlock_kernel();
341 return 0; 340 return 0;
342} 341}