summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2011-03-02 12:50:48 -0600
committerShaun Ruffell <sruffell@digium.com>2011-04-15 14:19:01 -0500
commit7bd29f1d446c26bce1add5e3da0e50de3daf44ae (patch)
treee3b9072d2e94ee8f4a9b61e5e08b748a1e240aab
parent6eae311e4ced7446d7c3fe2dd2511cc5e1d04a07 (diff)
wctdm24xxp: Make sure the interrupt handler isn't using the vpm instance.
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c62
1 files 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) = {