summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2011-11-07 22:40:20 +0000
committerShaun Ruffell <sruffell@digium.com>2011-11-07 22:40:20 +0000
commitadbe8be83cb1e8833383260ad9cc2fae6c638871 (patch)
tree3a2dbba0fbf5161e12c59ff2a690b7091d4e9ec9
parentb742903c986d4638edce98885810bff7e956c175 (diff)
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 <sruffell@digium.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10332 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c24
1 files changed, 24 insertions, 0 deletions
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)