From bc7c111d7e8c2217f8ab39f39bd7cdde03735736 Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Mon, 7 Nov 2011 22:40:20 +0000 Subject: [PATCH] wctdm24xxp: Wait for background threads to complete on failed load. Some of the VPM loading / probing threads use global system workqueues. They might now be running when we abort early so we should wait for them to complete their runs before freeing memory that may be in use. Signed-off-by: Shaun Ruffell git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10332 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/wctdm24xxp/base.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c index b3515f5..6d1f1c1 100644 --- a/drivers/dahdi/wctdm24xxp/base.c +++ b/drivers/dahdi/wctdm24xxp/base.c @@ -4937,8 +4937,30 @@ static void wctdm_back_out_gracefully(struct wctdm *wc) { int i; unsigned long flags; + struct vpmadt032 *vpm; LIST_HEAD(local_list); + spin_lock_irqsave(&wc->reglock, flags); + if (wc->not_ready) { + wc->not_ready--; + spin_unlock_irqrestore(&wc->reglock, flags); + while (wctdm_wait_for_ready(wc)) + schedule(); + spin_lock_irqsave(&wc->reglock, flags); + } + spin_unlock_irqrestore(&wc->reglock, flags); + + if (wc->vpmadt032) { + flush_workqueue(wc->vpmadt032->wq); + clear_bit(VPM150M_ACTIVE, &wc->vpmadt032->control); + flush_workqueue(wc->vpmadt032->wq); + spin_lock_irqsave(&wc->reglock, flags); + vpm = wc->vpmadt032; + wc->vpmadt032 = NULL; + spin_unlock_irqrestore(&wc->reglock, flags); + vpmadt032_free(vpm); + } + voicebus_release(&wc->vb); #ifdef CONFIG_VOICEBUS_ECREFERENCE for (i = 0; i < ARRAY_SIZE(wc->ec_reference); ++i) { @@ -5992,6 +6014,8 @@ static void __devexit wctdm_remove_one(struct pci_dev *pdev) schedule(); } + flush_scheduled_work(); + /* shut down any BRI modules */ for (i = 0; i < wc->mods_per_board; i += 4) { if (wc->mods[i].type == BRI)