From 7bd29f1d446c26bce1add5e3da0e50de3daf44ae Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Wed, 2 Mar 2011 12:50:48 -0600 Subject: wctdm24xxp: Make sure the interrupt handler isn't using the vpm instance. --- drivers/dahdi/wctdm24xxp/base.c | 62 ++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c index 02aab40..59aca50 100644 --- a/drivers/dahdi/wctdm24xxp/base.c +++ b/drivers/dahdi/wctdm24xxp/base.c @@ -4284,6 +4284,8 @@ static int wctdm_initialize_vpmadt032(struct wctdm *wc) { int res; struct vpmadt032_options options; + struct vpmadt032 *vpm; + unsigned long flags; options.debug = debug; options.vpmnlptype = vpmnlptype; @@ -4301,8 +4303,11 @@ static int wctdm_initialize_vpmadt032(struct wctdm *wc) * the analog channels. */ res = vpmadt032_init(wc->vpmadt032, &wc->vb); if (res) { - vpmadt032_free(wc->vpmadt032); + vpm = wc->vpmadt032; + spin_lock_irqsave(&wc->reglock, flags); wc->vpmadt032 = NULL; + spin_unlock_irqrestore(&wc->reglock, flags); + vpmadt032_free(vpm); return res; } @@ -4310,8 +4315,11 @@ static int wctdm_initialize_vpmadt032(struct wctdm *wc) * particular board. */ res = config_vpmadt032(wc->vpmadt032, wc); if (res) { - vpmadt032_free(wc->vpmadt032); + vpm = wc->vpmadt032; + spin_lock_irqsave(&wc->reglock, flags); wc->vpmadt032 = NULL; + spin_unlock_irqrestore(&wc->reglock, flags); + vpmadt032_free(vpm); return res; } @@ -5459,38 +5467,42 @@ static void wctdm_release(struct wctdm *wc) static void __devexit wctdm_remove_one(struct pci_dev *pdev) { struct wctdm *wc = pci_get_drvdata(pdev); - struct vpmadt032 *vpm = wc->vpmadt032; + struct vpmadt032 *vpm; int i; + unsigned long flags; + if (!wc) + return; - if (wc) { + remove_sysfs_files(wc); - remove_sysfs_files(wc); + vpm = wc->vpmadt032; + if (vpm) { + flush_workqueue(vpm->wq); + clear_bit(VPM150M_ACTIVE, &vpm->control); + flush_workqueue(vpm->wq); + } - if (vpm) { - flush_workqueue(vpm->wq); - clear_bit(VPM150M_ACTIVE, &vpm->control); - flush_workqueue(vpm->wq); - } + /* shut down any BRI modules */ + for (i = 0; i < wc->mods_per_board; i += 4) { + if (wc->mods[i].type == BRI) + wctdm_unload_b400m(wc, i); + } - /* shut down any BRI modules */ - for (i = 0; i < wc->mods_per_board; i += 4) { - if (wc->mods[i].type == BRI) - wctdm_unload_b400m(wc, i); - } + voicebus_stop(&wc->vb); - voicebus_stop(&wc->vb); + if (vpm) { + spin_lock_irqsave(&wc->reglock, flags); + wc->vpmadt032 = NULL; + spin_unlock_irqrestore(&wc->reglock, flags); + vpmadt032_free(vpm); + } - if (vpm) { - vpmadt032_free(wc->vpmadt032); - wc->vpmadt032 = NULL; - } + dev_info(&wc->vb.pdev->dev, + "Freed a %s\n", (is_hx8(wc)) ? "Hybrid card" : "Wildcard"); - dev_info(&wc->vb.pdev->dev, "Freed a %s\n", - (is_hx8(wc)) ? "Hybrid card" : "Wildcard"); - /* Release span */ - wctdm_release(wc); - } + /* Release span */ + wctdm_release(wc); } static DEFINE_PCI_DEVICE_TABLE(wctdm_pci_tbl) = { -- cgit v1.2.3