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) errcode = capi20_get_profile(0, &profile); if (errcode != CAPI_NOERROR) { + unregister_capictr_notifier(&capictr_nb); capi20_release(&global.ap); return -EIO; } 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 @@ #include <linux/rcupdate.h> static int showcapimsgs = 0; +static struct workqueue_struct *kcapi_wq; MODULE_DESCRIPTION("CAPI4Linux: kernel CAPI layer"); MODULE_AUTHOR("Carsten Paeth"); @@ -291,7 +292,7 @@ static int notify_push(unsigned int event_type, u32 controller) event->type = event_type; event->controller = controller; - schedule_work(&event->work); + queue_work(kcapi_wq, &event->work); return 0; } @@ -408,7 +409,7 @@ void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl, goto error; } skb_queue_tail(&ap->recv_queue, skb); - schedule_work(&ap->recv_work); + queue_work(kcapi_wq, &ap->recv_work); rcu_read_unlock(); return; @@ -743,7 +744,7 @@ u16 capi20_release(struct capi20_appl *ap) mutex_unlock(&capi_controller_lock); - flush_scheduled_work(); + flush_workqueue(kcapi_wq); skb_queue_purge(&ap->recv_queue); if (showcapimsgs & 1) { @@ -1285,21 +1286,30 @@ static int __init kcapi_init(void) { int err; + kcapi_wq = alloc_workqueue("kcapi", 0, 0); + if (!kcapi_wq) + return -ENOMEM; + register_capictr_notifier(&capictr_nb); err = cdebug_init(); - if (!err) - kcapi_proc_init(); - return err; + if (err) { + unregister_capictr_notifier(&capictr_nb); + destroy_workqueue(kcapi_wq); + return err; + } + + kcapi_proc_init(); + return 0; } static void __exit kcapi_exit(void) { kcapi_proc_exit(); - /* make sure all notifiers are finished */ - flush_scheduled_work(); + unregister_capictr_notifier(&capictr_nb); cdebug_exit(); + destroy_workqueue(kcapi_wq); } 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) } skb_queue_purge(&ch->squeue); skb_queue_purge(&ch->rqueue); - flush_scheduled_work(); + flush_work_sync(&ch->workq); return 0; } EXPORT_SYMBOL(mISDN_freedchannel); @@ -143,7 +143,7 @@ mISDN_freebchannel(struct bchannel *ch) mISDN_clear_bchannel(ch); skb_queue_purge(&ch->rqueue); ch->rcount = 0; - flush_scheduled_work(); + flush_work_sync(&ch->workq); return 0; } 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) if (timer_pending(&hc->timeout_tl)) del_timer(&hc->timeout_tl); + cancel_work_sync(&hc->workq); + if (hc->socket_thread) l1oip_socket_close(hc); |