linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / isdn / capi / capi.c
index 669f763..623adbb 100644 (file)
@@ -9,6 +9,7 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -38,6 +39,7 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/moduleparam.h>
+#include <linux/devfs_fs_kernel.h>
 #include <linux/isdn/capiutil.h>
 #include <linux/isdn/capicmd.h>
 #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
@@ -85,11 +87,6 @@ struct capincci;
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 struct capiminor;
 
-struct datahandle_queue {
-       struct list_head        list;
-       u16                     datahandle;
-};
-
 struct capiminor {
        struct list_head list;
        struct capincci  *nccip;
@@ -112,9 +109,12 @@ struct capiminor {
        int                 outbytes;
 
        /* transmit path */
-       struct list_head ackqueue;
+       struct datahandle_queue {
+                   struct datahandle_queue *next;
+                   u16                    datahandle;
+       } *ackqueue;
        int nack;
-       spinlock_t ackqlock;
+
 };
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
@@ -156,54 +156,48 @@ static LIST_HEAD(capiminor_list);
 
 static int capincci_add_ack(struct capiminor *mp, u16 datahandle)
 {
-       struct datahandle_queue *n;
-       unsigned long flags;
+       struct datahandle_queue *n, **pp;
 
        n = kmalloc(sizeof(*n), GFP_ATOMIC);
-       if (unlikely(!n)) {
-               printk(KERN_ERR "capi: alloc datahandle failed\n");
-               return -1;
+       if (!n) {
+          printk(KERN_ERR "capi: alloc datahandle failed\n");
+          return -1;
        }
+       n->next = NULL;
        n->datahandle = datahandle;
-       INIT_LIST_HEAD(&n->list);
-       spin_lock_irqsave(&mp->ackqlock, flags);
-       list_add_tail(&n->list, &mp->ackqueue);
+       for (pp = &mp->ackqueue; *pp; pp = &(*pp)->next) ;
+       *pp = n;
        mp->nack++;
-       spin_unlock_irqrestore(&mp->ackqlock, flags);
        return 0;
 }
 
 static int capiminor_del_ack(struct capiminor *mp, u16 datahandle)
 {
-       struct datahandle_queue *p, *tmp;
-       unsigned long flags;
+       struct datahandle_queue **pp, *p;
 
-       spin_lock_irqsave(&mp->ackqlock, flags);
-       list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
-               if (p->datahandle == datahandle) {
-                       list_del(&p->list);
+       for (pp = &mp->ackqueue; *pp; pp = &(*pp)->next) {
+               if ((*pp)->datahandle == datahandle) {
+                       p = *pp;
+                       *pp = (*pp)->next;
                        kfree(p);
                        mp->nack--;
-                       spin_unlock_irqrestore(&mp->ackqlock, flags);
                        return 0;
                }
        }
-       spin_unlock_irqrestore(&mp->ackqlock, flags);
        return -1;
 }
 
 static void capiminor_del_all_ack(struct capiminor *mp)
 {
-       struct datahandle_queue *p, *tmp;
-       unsigned long flags;
+       struct datahandle_queue **pp, *p;
 
-       spin_lock_irqsave(&mp->ackqlock, flags);
-       list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
-               list_del(&p->list);
+       pp = &mp->ackqueue;
+       while (*pp) {
+               p = *pp;
+               *pp = (*pp)->next;
                kfree(p);
                mp->nack--;
        }
-       spin_unlock_irqrestore(&mp->ackqlock, flags);
 }
 
 
@@ -226,8 +220,6 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
        mp->ncci = ncci;
        mp->msgid = 0;
        atomic_set(&mp->ttyopencount,0);
-       INIT_LIST_HEAD(&mp->ackqueue);
-       spin_lock_init(&mp->ackqlock);
 
        skb_queue_head_init(&mp->inqueue);
        skb_queue_head_init(&mp->outqueue);
@@ -1335,6 +1327,7 @@ static int capinc_tty_init(void)
 
        drv->owner = THIS_MODULE;
        drv->driver_name = "capi_nc";
+       drv->devfs_name = "capi/";
        drv->name = "capi";
        drv->major = capi_ttymajor;
        drv->minor_start = 0;
@@ -1492,7 +1485,6 @@ static int __init capi_init(void)
 {
        char *p;
        char *compileinfo;
-       int major_ret;
 
        if ((p = strchr(revision, ':')) != 0 && p[1]) {
                strlcpy(rev, p + 2, sizeof(rev));
@@ -1501,11 +1493,11 @@ static int __init capi_init(void)
        } else
                strcpy(rev, "1.0");
 
-       major_ret = register_chrdev(capi_major, "capi20", &capi_fops);
-       if (major_ret < 0) {
+       if (register_chrdev(capi_major, "capi20", &capi_fops)) {
                printk(KERN_ERR "capi20: unable to get major %d\n", capi_major);
-               return major_ret;
+               return -EIO;
        }
+
        capi_class = class_create(THIS_MODULE, "capi");
        if (IS_ERR(capi_class)) {
                unregister_chrdev(capi_major, "capi20");
@@ -1513,6 +1505,8 @@ static int __init capi_init(void)
        }
 
        class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
+       devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR,
+                       "isdn/capi20");
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
        if (capinc_tty_init() < 0) {
@@ -1547,6 +1541,7 @@ static void __exit capi_exit(void)
        class_device_destroy(capi_class, MKDEV(capi_major, 0));
        class_destroy(capi_class);
        unregister_chrdev(capi_major, "capi20");
+       devfs_remove("isdn/capi20");
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
        capinc_tty_exit();