aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/capi/capidrv.c1
-rw-r--r--drivers/isdn/capi/kcapi.c26
-rw-r--r--drivers/isdn/mISDN/hwchannel.c4
-rw-r--r--drivers/isdn/mISDN/l1oip_core.c2
4 files changed, 23 insertions, 10 deletions
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index e54e79d4e2c1..92607ed25e2e 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -2297,6 +2297,7 @@ static int __init capidrv_init(void)
2297 2297
2298 errcode = capi20_get_profile(0, &profile); 2298 errcode = capi20_get_profile(0, &profile);
2299 if (errcode != CAPI_NOERROR) { 2299 if (errcode != CAPI_NOERROR) {
2300 unregister_capictr_notifier(&capictr_nb);
2300 capi20_release(&global.ap); 2301 capi20_release(&global.ap);
2301 return -EIO; 2302 return -EIO;
2302 } 2303 }
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index 3acf94cc5acd..2b33b2627fce 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -38,6 +38,7 @@
38#include <linux/rcupdate.h> 38#include <linux/rcupdate.h>
39 39
40static int showcapimsgs = 0; 40static int showcapimsgs = 0;
41static struct workqueue_struct *kcapi_wq;
41 42
42MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer"); 43MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer");
43MODULE_AUTHOR("Carsten Paeth"); 44MODULE_AUTHOR("Carsten Paeth");
@@ -291,7 +292,7 @@ static int notify_push(unsigned int event_type, u32 controller)
291 event->type = event_type; 292 event->type = event_type;
292 event->controller = controller; 293 event->controller = controller;
293 294
294 schedule_work(&event->work); 295 queue_work(kcapi_wq, &event->work);
295 return 0; 296 return 0;
296} 297}
297 298
@@ -408,7 +409,7 @@ void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
408 goto error; 409 goto error;
409 } 410 }
410 skb_queue_tail(&ap->recv_queue, skb); 411 skb_queue_tail(&ap->recv_queue, skb);
411 schedule_work(&ap->recv_work); 412 queue_work(kcapi_wq, &ap->recv_work);
412 rcu_read_unlock(); 413 rcu_read_unlock();
413 414
414 return; 415 return;
@@ -743,7 +744,7 @@ u16 capi20_release(struct capi20_appl *ap)
743 744
744 mutex_unlock(&capi_controller_lock); 745 mutex_unlock(&capi_controller_lock);
745 746
746 flush_scheduled_work(); 747 flush_workqueue(kcapi_wq);
747 skb_queue_purge(&ap->recv_queue); 748 skb_queue_purge(&ap->recv_queue);
748 749
749 if (showcapimsgs & 1) { 750 if (showcapimsgs & 1) {
@@ -1285,21 +1286,30 @@ static int __init kcapi_init(void)
1285{ 1286{
1286 int err; 1287 int err;
1287 1288
1289 kcapi_wq = alloc_workqueue("kcapi", 0, 0);
1290 if (!kcapi_wq)
1291 return -ENOMEM;
1292
1288 register_capictr_notifier(&capictr_nb); 1293 register_capictr_notifier(&capictr_nb);
1289 1294
1290 err = cdebug_init(); 1295 err = cdebug_init();
1291 if (!err) 1296 if (err) {
1292 kcapi_proc_init(); 1297 unregister_capictr_notifier(&capictr_nb);
1293 return err; 1298 destroy_workqueue(kcapi_wq);
1299 return err;
1300 }
1301
1302 kcapi_proc_init();
1303 return 0;
1294} 1304}
1295 1305
1296static void __exit kcapi_exit(void) 1306static void __exit kcapi_exit(void)
1297{ 1307{
1298 kcapi_proc_exit(); 1308 kcapi_proc_exit();
1299 1309
1300 /* make sure all notifiers are finished */ 1310 unregister_capictr_notifier(&capictr_nb);
1301 flush_scheduled_work();
1302 cdebug_exit(); 1311 cdebug_exit();
1312 destroy_workqueue(kcapi_wq);
1303} 1313}
1304 1314
1305module_init(kcapi_init); 1315module_init(kcapi_init);
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c
index 307bd6e8988b..199f374cf9da 100644
--- a/drivers/isdn/mISDN/hwchannel.c
+++ b/drivers/isdn/mISDN/hwchannel.c
@@ -110,7 +110,7 @@ mISDN_freedchannel(struct dchannel *ch)
110 } 110 }
111 skb_queue_purge(&ch->squeue); 111 skb_queue_purge(&ch->squeue);
112 skb_queue_purge(&ch->rqueue); 112 skb_queue_purge(&ch->rqueue);
113 flush_scheduled_work(); 113 flush_work_sync(&ch->workq);
114 return 0; 114 return 0;
115} 115}
116EXPORT_SYMBOL(mISDN_freedchannel); 116EXPORT_SYMBOL(mISDN_freedchannel);
@@ -143,7 +143,7 @@ mISDN_freebchannel(struct bchannel *ch)
143 mISDN_clear_bchannel(ch); 143 mISDN_clear_bchannel(ch);
144 skb_queue_purge(&ch->rqueue); 144 skb_queue_purge(&ch->rqueue);
145 ch->rcount = 0; 145 ch->rcount = 0;
146 flush_scheduled_work(); 146 flush_work_sync(&ch->workq);
147 return 0; 147 return 0;
148} 148}
149EXPORT_SYMBOL(mISDN_freebchannel); 149EXPORT_SYMBOL(mISDN_freebchannel);
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
index 5b59796ed250..bd526f664a39 100644
--- a/drivers/isdn/mISDN/l1oip_core.c
+++ b/drivers/isdn/mISDN/l1oip_core.c
@@ -1269,6 +1269,8 @@ release_card(struct l1oip *hc)
1269 if (timer_pending(&hc->timeout_tl)) 1269 if (timer_pending(&hc->timeout_tl))
1270 del_timer(&hc->timeout_tl); 1270 del_timer(&hc->timeout_tl);
1271 1271
1272 cancel_work_sync(&hc->workq);
1273
1272 if (hc->socket_thread) 1274 if (hc->socket_thread)
1273 l1oip_socket_close(hc); 1275 l1oip_socket_close(hc);
1274 1276