diff options
Diffstat (limited to 'drivers/isdn')
-rw-r--r-- | drivers/isdn/capi/capi.c | 52 |
1 files changed, 20 insertions, 32 deletions
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 8abec9655e1a..6704b2b004aa 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -122,7 +122,7 @@ struct capiminor { | |||
122 | static DEFINE_SPINLOCK(workaround_lock); | 122 | static DEFINE_SPINLOCK(workaround_lock); |
123 | 123 | ||
124 | struct capincci { | 124 | struct capincci { |
125 | struct capincci *next; | 125 | struct list_head list; |
126 | u32 ncci; | 126 | u32 ncci; |
127 | struct capidev *cdev; | 127 | struct capidev *cdev; |
128 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 128 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE |
@@ -139,7 +139,7 @@ struct capidev { | |||
139 | struct sk_buff_head recvqueue; | 139 | struct sk_buff_head recvqueue; |
140 | wait_queue_head_t recvwait; | 140 | wait_queue_head_t recvwait; |
141 | 141 | ||
142 | struct capincci *nccis; | 142 | struct list_head nccis; |
143 | 143 | ||
144 | struct mutex lock; | 144 | struct mutex lock; |
145 | }; | 145 | }; |
@@ -356,7 +356,7 @@ static inline unsigned int capincci_minor_opencount(struct capincci *np) | |||
356 | 356 | ||
357 | static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci) | 357 | static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci) |
358 | { | 358 | { |
359 | struct capincci *np, **pp; | 359 | struct capincci *np; |
360 | 360 | ||
361 | np = kzalloc(sizeof(*np), GFP_KERNEL); | 361 | np = kzalloc(sizeof(*np), GFP_KERNEL); |
362 | if (!np) | 362 | if (!np) |
@@ -366,39 +366,31 @@ static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci) | |||
366 | 366 | ||
367 | capincci_alloc_minor(cdev, np); | 367 | capincci_alloc_minor(cdev, np); |
368 | 368 | ||
369 | for (pp=&cdev->nccis; *pp; pp = &(*pp)->next) | 369 | list_add_tail(&np->list, &cdev->nccis); |
370 | ; | 370 | |
371 | *pp = np; | 371 | return np; |
372 | return np; | ||
373 | } | 372 | } |
374 | 373 | ||
375 | static void capincci_free(struct capidev *cdev, u32 ncci) | 374 | static void capincci_free(struct capidev *cdev, u32 ncci) |
376 | { | 375 | { |
377 | struct capincci *np, **pp; | 376 | struct capincci *np, *tmp; |
378 | 377 | ||
379 | pp=&cdev->nccis; | 378 | list_for_each_entry_safe(np, tmp, &cdev->nccis, list) |
380 | while (*pp) { | ||
381 | np = *pp; | ||
382 | if (ncci == 0xffffffff || np->ncci == ncci) { | 379 | if (ncci == 0xffffffff || np->ncci == ncci) { |
383 | *pp = (*pp)->next; | ||
384 | capincci_free_minor(np); | 380 | capincci_free_minor(np); |
381 | list_del(&np->list); | ||
385 | kfree(np); | 382 | kfree(np); |
386 | if (*pp == NULL) return; | ||
387 | } else { | ||
388 | pp = &(*pp)->next; | ||
389 | } | 383 | } |
390 | } | ||
391 | } | 384 | } |
392 | 385 | ||
393 | static struct capincci *capincci_find(struct capidev *cdev, u32 ncci) | 386 | static struct capincci *capincci_find(struct capidev *cdev, u32 ncci) |
394 | { | 387 | { |
395 | struct capincci *p; | 388 | struct capincci *np; |
396 | 389 | ||
397 | for (p=cdev->nccis; p ; p = p->next) { | 390 | list_for_each_entry(np, &cdev->nccis, list) |
398 | if (p->ncci == ncci) | 391 | if (np->ncci == ncci) |
399 | break; | 392 | return np; |
400 | } | 393 | return NULL; |
401 | return p; | ||
402 | } | 394 | } |
403 | 395 | ||
404 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 396 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE |
@@ -955,6 +947,7 @@ static int capi_open(struct inode *inode, struct file *file) | |||
955 | mutex_init(&cdev->lock); | 947 | mutex_init(&cdev->lock); |
956 | skb_queue_head_init(&cdev->recvqueue); | 948 | skb_queue_head_init(&cdev->recvqueue); |
957 | init_waitqueue_head(&cdev->recvwait); | 949 | init_waitqueue_head(&cdev->recvwait); |
950 | INIT_LIST_HEAD(&cdev->nccis); | ||
958 | file->private_data = cdev; | 951 | file->private_data = cdev; |
959 | 952 | ||
960 | mutex_lock(&capidev_list_lock); | 953 | mutex_lock(&capidev_list_lock); |
@@ -1427,19 +1420,14 @@ static const struct file_operations capi20_proc_fops = { | |||
1427 | */ | 1420 | */ |
1428 | static int capi20ncci_proc_show(struct seq_file *m, void *v) | 1421 | static int capi20ncci_proc_show(struct seq_file *m, void *v) |
1429 | { | 1422 | { |
1430 | struct capidev *cdev; | 1423 | struct capidev *cdev; |
1431 | struct capincci *np; | 1424 | struct capincci *np; |
1432 | struct list_head *l; | ||
1433 | 1425 | ||
1434 | mutex_lock(&capidev_list_lock); | 1426 | mutex_lock(&capidev_list_lock); |
1435 | list_for_each(l, &capidev_list) { | 1427 | list_for_each_entry(cdev, &capidev_list, list) { |
1436 | cdev = list_entry(l, struct capidev, list); | ||
1437 | mutex_lock(&cdev->lock); | 1428 | mutex_lock(&cdev->lock); |
1438 | for (np=cdev->nccis; np; np = np->next) { | 1429 | list_for_each_entry(np, &cdev->nccis, list) |
1439 | seq_printf(m, "%d 0x%x\n", | 1430 | seq_printf(m, "%d 0x%x\n", cdev->ap.applid, np->ncci); |
1440 | cdev->ap.applid, | ||
1441 | np->ncci); | ||
1442 | } | ||
1443 | mutex_unlock(&cdev->lock); | 1431 | mutex_unlock(&cdev->lock); |
1444 | } | 1432 | } |
1445 | mutex_unlock(&capidev_list_lock); | 1433 | mutex_unlock(&capidev_list_lock); |