aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/isdn/capi/capi.c93
1 files changed, 34 insertions, 59 deletions
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 623412e22c14..9d7c3692c7d7 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -401,46 +401,6 @@ static struct capincci *capincci_find(struct capidev *cdev, u32 ncci)
401 return p; 401 return p;
402} 402}
403 403
404/* -------- struct capidev ------------------------------------------ */
405
406static struct capidev *capidev_alloc(void)
407{
408 struct capidev *cdev;
409
410 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
411 if (!cdev)
412 return NULL;
413
414 mutex_init(&cdev->ncci_list_mtx);
415 skb_queue_head_init(&cdev->recvqueue);
416 init_waitqueue_head(&cdev->recvwait);
417
418 mutex_lock(&capidev_list_lock);
419 list_add_tail(&cdev->list, &capidev_list);
420 mutex_unlock(&capidev_list_lock);
421
422 return cdev;
423}
424
425static void capidev_free(struct capidev *cdev)
426{
427 mutex_lock(&capidev_list_lock);
428 list_del(&cdev->list);
429 mutex_unlock(&capidev_list_lock);
430
431 if (cdev->ap.applid) {
432 capi20_release(&cdev->ap);
433 cdev->ap.applid = 0;
434 }
435 skb_queue_purge(&cdev->recvqueue);
436
437 mutex_lock(&cdev->ncci_list_mtx);
438 capincci_free(cdev, 0xffffffff);
439 mutex_unlock(&cdev->ncci_list_mtx);
440
441 kfree(cdev);
442}
443
444#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 404#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
445/* -------- handle data queue --------------------------------------- */ 405/* -------- handle data queue --------------------------------------- */
446 406
@@ -991,30 +951,45 @@ capi_ioctl(struct inode *inode, struct file *file,
991 return -EINVAL; 951 return -EINVAL;
992} 952}
993 953
994static int 954static int capi_open(struct inode *inode, struct file *file)
995capi_open(struct inode *inode, struct file *file)
996{ 955{
997 int ret; 956 struct capidev *cdev;
998 957
999 lock_kernel(); 958 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
1000 if (file->private_data) 959 if (!cdev)
1001 ret = -EEXIST; 960 return -ENOMEM;
1002 else if ((file->private_data = capidev_alloc()) == NULL) 961
1003 ret = -ENOMEM; 962 mutex_init(&cdev->ncci_list_mtx);
1004 else 963 skb_queue_head_init(&cdev->recvqueue);
1005 ret = nonseekable_open(inode, file); 964 init_waitqueue_head(&cdev->recvwait);
1006 unlock_kernel(); 965 file->private_data = cdev;
1007 return ret; 966
967 mutex_lock(&capidev_list_lock);
968 list_add_tail(&cdev->list, &capidev_list);
969 mutex_unlock(&capidev_list_lock);
970
971 return nonseekable_open(inode, file);
1008} 972}
1009 973
1010static int 974static int capi_release(struct inode *inode, struct file *file)
1011capi_release(struct inode *inode, struct file *file)
1012{ 975{
1013 struct capidev *cdev = (struct capidev *)file->private_data; 976 struct capidev *cdev = file->private_data;
1014 977
1015 capidev_free(cdev); 978 mutex_lock(&capidev_list_lock);
1016 file->private_data = NULL; 979 list_del(&cdev->list);
1017 980 mutex_unlock(&capidev_list_lock);
981
982 if (cdev->ap.applid) {
983 capi20_release(&cdev->ap);
984 cdev->ap.applid = 0;
985 }
986 skb_queue_purge(&cdev->recvqueue);
987
988 mutex_lock(&cdev->ncci_list_mtx);
989 capincci_free(cdev, 0xffffffff);
990 mutex_unlock(&cdev->ncci_list_mtx);
991
992 kfree(cdev);
1018 return 0; 993 return 0;
1019} 994}
1020 995