summaryrefslogtreecommitdiff
path: root/wcfxo.c
diff options
context:
space:
mode:
Diffstat (limited to 'wcfxo.c')
-rwxr-xr-xwcfxo.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/wcfxo.c b/wcfxo.c
index 17c3621..fb12d73 100755
--- a/wcfxo.c
+++ b/wcfxo.c
@@ -403,10 +403,9 @@ static void wcfxo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
if (ints & 0x10) {
- printk("PCI Master abort\n");
- /* Stop DMA and start it again */
+ printk("FXO PCI Master abort\n");
+ /* Stop DMA andlet the watchdog start it again */
wcfxo_stop_dma(wc);
- wcfxo_restart_dma(wc);
return;
}
@@ -513,6 +512,13 @@ static int wcfxo_open(struct zt_chan *chan)
return 0;
}
+static int wcfxo_watchdog(struct zt_span *span, int event)
+{
+ printk("FXO: Restarting DMA\n");
+ wcfxo_restart_dma(span->pvt);
+ return 0;
+}
+
static int wcfxo_close(struct zt_chan *chan)
{
struct wcfxo *wc = chan->pvt;
@@ -582,6 +588,7 @@ static int wcfxo_initialize(struct wcfxo *wc)
wc->span.close = wcfxo_close;
wc->span.flags = ZT_FLAG_RBS;
wc->span.deflaw = ZT_LAW_MULAW;
+ wc->span.watchdog = wcfxo_watchdog;
#ifdef ENABLE_TASKLETS
tasklet_init(&wc->wcfxo_tlet, wcfxo_tasklet, (unsigned long)wc);
#endif
@@ -666,12 +673,7 @@ static void wcfxo_start_dma(struct wcfxo *wc)
static void wcfxo_restart_dma(struct wcfxo *wc)
{
- int x;
/* Reset Master and TDM */
- outb(0x0f, wc->ioaddr + WC_CNTL);
- /* Can't really wait, so simulate a wait */
- for (x=0;x<100;x++)
- inb( wc->ioaddr + WC_CNTL);
outb(0x01, wc->ioaddr + WC_CNTL);
outb(0x01, wc->ioaddr + WC_OPER);
}
@@ -682,6 +684,12 @@ static void wcfxo_stop_dma(struct wcfxo *wc)
outb(0x00, wc->ioaddr + WC_OPER);
}
+static void wcfxo_reset_tdm(struct wcfxo *wc)
+{
+ /* Reset TDM */
+ outb(0x0f, wc->ioaddr + WC_CNTL);
+}
+
static void wcfxo_disable_interrupts(struct wcfxo *wc)
{
outb(0x00, wc->ioaddr + WC_MASK0);
@@ -872,6 +880,7 @@ static void __devexit wcfxo_remove_one(struct pci_dev *pdev)
/* Stop any DMA */
wcfxo_stop_dma(wc);
+ wcfxo_reset_tdm(wc);
/* In case hardware is still there */
wcfxo_disable_interrupts(wc);