X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fisdn%2Fcapi%2Fcapi.c;fp=drivers%2Fisdn%2Fcapi%2Fcapi.c;h=623adbb0d13abe8098912f0203c9218211967019;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=669f76393b5a5128de344b0cc7b7b1cda40179e2;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 669f76393..623adbb0d 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -9,6 +9,7 @@ * */ +#include #include #include #include @@ -38,6 +39,7 @@ #include #include #include +#include #include #include #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();