diff options
Diffstat (limited to 'drivers/isdn')
-rw-r--r-- | drivers/isdn/capi/capidrv.c | 1 | ||||
-rw-r--r-- | drivers/isdn/capi/kcapi.c | 26 | ||||
-rw-r--r-- | drivers/isdn/mISDN/hwchannel.c | 4 | ||||
-rw-r--r-- | drivers/isdn/mISDN/l1oip_core.c | 2 |
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 | ||
40 | static int showcapimsgs = 0; | 40 | static int showcapimsgs = 0; |
41 | static struct workqueue_struct *kcapi_wq; | ||
41 | 42 | ||
42 | MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer"); | 43 | MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer"); |
43 | MODULE_AUTHOR("Carsten Paeth"); | 44 | MODULE_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 | ||
1296 | static void __exit kcapi_exit(void) | 1306 | static 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 | ||
1305 | module_init(kcapi_init); | 1315 | module_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 | } |
116 | EXPORT_SYMBOL(mISDN_freedchannel); | 116 | EXPORT_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 | } |
149 | EXPORT_SYMBOL(mISDN_freebchannel); | 149 | EXPORT_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 | ||