summaryrefslogtreecommitdiff
path: root/wcte12xp
diff options
context:
space:
mode:
authorsruffell <sruffell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-04-03 21:37:11 +0000
committersruffell <sruffell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-04-03 21:37:11 +0000
commit58853d266e3a76137b4f0da3d91c627ef6b7c94e (patch)
tree6e1b5837ef7a8bd6a9666fb5f0225d96f7d5d22b /wcte12xp
parentb88dcb40c9342fa0307e9c8d020db3fbba699c62 (diff)
svn merge -c4096 https://origsvn.digium.com/svn/zaptel/branches/1.4/kernel/wctdm24xxp wctdm24xxp
svn merge -c4096 https://origsvn.digium.com/svn/zaptel/branches/1.4/kernel/wcte12xp wcte12xp svn cp https://origsvn.digium.com/svn/zaptel/branches/1.4/kernel/voicebus.c . svn cp https://origsvn.digium.com/svn/zaptel/branches/1.4/kernel/voicebus.h . svn cp https://origsvn.digium.com/svn/zaptel/branches/1.4/kernel/fxo_modes.h . git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@4129 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'wcte12xp')
-rw-r--r--wcte12xp/Kbuild2
-rw-r--r--wcte12xp/base.c608
-rw-r--r--wcte12xp/vpmadt032.c84
-rw-r--r--wcte12xp/wcte12xp.h19
4 files changed, 118 insertions, 595 deletions
diff --git a/wcte12xp/Kbuild b/wcte12xp/Kbuild
index 15530ce..cd03c35 100644
--- a/wcte12xp/Kbuild
+++ b/wcte12xp/Kbuild
@@ -6,7 +6,7 @@ ifeq ($(HOTPLUG_FIRMWARE),yes)
EXTRA_CFLAGS += -DHOTPLUG_FIRMWARE
endif
-wcte12xp-objs := base.o vpmadt032.o GpakApi.o
+wcte12xp-objs := base.o vpmadt032.o GpakApi.o ../voicebus.o
ifneq ($(HOTPLUG_FIRMWARE),yes)
wcte12xp-objs += firmware_vpmadt032.o
diff --git a/wcte12xp/base.c b/wcte12xp/base.c
index ced5103..cd8c0d6 100644
--- a/wcte12xp/base.c
+++ b/wcte12xp/base.c
@@ -8,7 +8,7 @@
* Matthew Fredrickson <creslin@digium.com>
* William Meadows <wmeadows@digium.com>
*
- * Copyright (C) 2007, Digium, Inc.
+ * Copyright (C) 2007-2008, Digium, Inc.
*
* All rights reserved.
*
@@ -34,9 +34,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/pci.h>
-#include <linux/interrupt.h>
#include <linux/proc_fs.h>
-#include <linux/interrupt.h>
#ifdef LINUX26
#include <linux/moduleparam.h>
@@ -46,6 +44,7 @@
#include "../wct4xxp/wct4xxp.h" /* For certain definitions */
+#include "../voicebus.h"
#include "wcte12xp.h"
#include "vpmadt032.h"
#include "GpakApi.h"
@@ -88,6 +87,7 @@ static int alarmdebounce = 0;
static int loopback = 0;
static int t1e1override = -1;
static int unchannelized = 0;
+static int latency = VOICEBUS_DEFAULT_LATENCY;
#ifdef VPM_SUPPORT
int vpmsupport = 1;
int vpmdtmfsupport = 0;
@@ -132,89 +132,6 @@ static inline int empty_slot(struct t1 *wc)
return -1;
}
-static inline void __t1_setctl(struct t1 *wc, unsigned int addr, unsigned int val)
-{
- outl(val, wc->iobase + addr);
-}
-
-static inline void t1_setctl(struct t1 *wc, unsigned int addr, unsigned int val)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&wc->reglock, flags);
- __t1_setctl(wc, addr, val);
- spin_unlock_irqrestore(&wc->reglock, flags);
-}
-
-static inline unsigned int __t1_getctl(struct t1 *wc, unsigned int addr)
-{
- return inl(wc->iobase + addr);
-}
-
-static inline unsigned int t1_getctl(struct t1 *wc, unsigned int addr)
-{
- unsigned long flags;
- unsigned int val;
-
- spin_lock_irqsave(&wc->reglock, flags);
- val = __t1_getctl(wc, addr);
- spin_unlock_irqrestore(&wc->reglock, flags);
-
- return val;
-}
-
-static void t1_init_descriptors(struct t1 *wc)
-{
- volatile unsigned int *descrip;
- dma_addr_t descripdma;
- dma_addr_t writedma;
- dma_addr_t readdma;
- int x;
-
- descrip = wc->descripchunk;
- descripdma = wc->descripdma;
- writedma = wc->writedma;
- readdma = wc->readdma;
-
- for (x = 0; x < ERING_SIZE; x++) {
- if (x < ERING_SIZE - 1)
- descripdma += 16;
- else
- descripdma = wc->descripdma;
-
- /* Transmit descriptor */
- descrip[0] = 0x80000000;
- descrip[1] = 0xe5800000 | (SFRAME_SIZE);
- if (x % 2)
- descrip[2] = writedma + SFRAME_SIZE;
- else
- descrip[2] = writedma;
- descrip[3] = descripdma;
-
- /* Receive descriptor */
- descrip[0 + ERING_SIZE * 4] = 0x80000000;
- descrip[1 + ERING_SIZE * 4] = 0x01000000 | (SFRAME_SIZE);
- if (x % 2)
- descrip[2 + ERING_SIZE * 4] = readdma + SFRAME_SIZE;
- else
- descrip[2 + ERING_SIZE * 4] = readdma;
- descrip[3 + ERING_SIZE * 4] = descripdma + ERING_SIZE * 16;
-
- /* Advance descriptor */
- descrip += 4;
- }
-}
-
-static inline void t1_reinit_descriptor(struct t1 *wc, int tx, int dbl, char *s)
-{
- int o2 = dbl * 4;
-
- if (!tx)
- o2 += ERING_SIZE * 4;
-
- wc->descripchunk[o2] = 0x80000000;
-}
-
static inline void cmd_dequeue(struct t1 *wc, volatile unsigned char *writechunk, int eframe, int slot)
{
struct command *curcmd=NULL;
@@ -287,93 +204,6 @@ static inline void cmd_decipher(struct t1 *wc, volatile unsigned char *readchunk
}
}
-static inline unsigned int __t1_sdi_clk(struct t1 *wc)
-{
- unsigned int ret;
-
- wc->sdi &= ~SDI_CLK;
- __t1_setctl(wc, 0x0048, wc->sdi);
- ret = __t1_getctl(wc, 0x0048);
- wc->sdi |= SDI_CLK;
- __t1_setctl(wc, 0x0048, wc->sdi);
- return ret & SDI_DIN;
-}
-
-static inline void __t1_sdi_sendbits(struct t1 *wc, unsigned int bits, int count)
-{
- wc->sdi &= ~SDI_DREAD;
- __t1_setctl(wc, 0x0048, wc->sdi);
- while (count--) {
- if (bits & (1 << count))
- wc->sdi |= SDI_DOUT;
- else
- wc->sdi &= ~SDI_DOUT;
- __t1_sdi_clk(wc);
- }
-}
-
-static inline unsigned int __t1_sdi_recvbits(struct t1 *wc, int count)
-{
- unsigned int bits=0;
-
- wc->sdi |= SDI_DREAD;
- __t1_setctl(wc, 0x0048, wc->sdi);
- while (count--) {
- bits <<= 1;
- if (__t1_sdi_clk(wc))
- bits |= 1;
- else
- bits &= ~1;
- }
- return bits;
-}
-
-static inline unsigned short __t1_getsdi(struct t1 *wc, unsigned char addr)
-{
- unsigned int bits;
-
- /* Send preamble */
- bits = 0xffffffff;
- __t1_sdi_sendbits(wc, bits, 32);
- bits = (0x6 << 10) | (1 << 5) | (addr);
- __t1_sdi_sendbits(wc, bits, 14);
-
- return __t1_sdi_recvbits(wc, 18);
-}
-
-static inline unsigned short t1_getsdi(struct t1 *wc, unsigned char addr)
-{
- unsigned long flags;
- unsigned short val;
-
- spin_lock_irqsave(&wc->reglock, flags);
- val = __t1_getsdi(wc, addr);
- spin_unlock_irqrestore(&wc->reglock, flags);
-
- return val;
-}
-
-static inline void __t1_setsdi(struct t1 *wc, unsigned char addr, unsigned short value)
-{
- unsigned int bits;
-
- /* Send preamble */
- bits = 0xffffffff;
- __t1_sdi_sendbits(wc, bits, 32);
- bits = (0x5 << 12) | (1 << 7) | (addr << 2) | 0x2;
- __t1_sdi_sendbits(wc, bits, 16);
- __t1_sdi_sendbits(wc, value, 16);
-}
-
-static inline void t1_setsdi(struct t1 *wc, unsigned char addr, unsigned short value)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&wc->reglock, flags);
- __t1_setsdi(wc, addr, value);
- spin_unlock_irqrestore(&wc->reglock, flags);
-}
-
static inline int t1_setreg_full(struct t1 *wc, int addr, int val, int inisr, int vpm_num)
{
unsigned long flags;
@@ -448,10 +278,16 @@ static inline int t1_getreg_isr(struct t1 *wc, int addr)
/* find our requested command */
for (x = 0;x < sizeof(wc->cmdq.cmds) / sizeof(wc->cmdq.cmds[0]); x++) {
if ((wc->cmdq.cmds[x].flags & __CMD_RD) &&
- (wc->cmdq.cmds[x].flags & __CMD_FIN) &&
- (wc->cmdq.cmds[x].address==addr)) {
- hit = x;
- break;
+ (wc->cmdq.cmds[x].address==addr))
+ {
+ if (wc->cmdq.cmds[x].flags & __CMD_FIN) {
+ hit = x;
+ break;
+ }
+ else {
+ /* still in progress. */
+ return -1;
+ }
}
}
@@ -592,68 +428,6 @@ static inline int t1_getpins(struct t1 *wc, int inisr)
return ret;
}
-static void t1_setintmask(struct t1 *wc, unsigned int intmask)
-{
- wc->intmask = intmask;
- t1_setctl(wc, 0x0038, intmask);
-}
-
-static void t1_enable_interrupts(struct t1 *wc)
-{
- /* Enable interrupts */
- t1_setintmask(wc, 0x00010041); /* only RX */
-}
-
-static void t1_disable_interrupts(struct t1 *wc)
-{
- /* Disable interrupts */
- t1_setintmask(wc, 0x00000000);
- t1_setctl(wc, 0x0084, 0x00000000);
-}
-
-static void t1_start_dma(struct t1 *wc)
-{
- unsigned int reg;
- int x;
-
- wmb();
- t1_setctl(wc, 0x0020, wc->descripdma);
- t1_setctl(wc, 0x0018, wc->descripdma + (16 * ERING_SIZE));
- /* Start receiver/transmitter */
- reg = t1_getctl(wc, 0x0030);
- t1_setctl(wc, 0x0030, reg | 0x00002002);
- t1_setctl(wc, 0x0008, 0x00000000);
- t1_setctl(wc, 0x0010, 0x00000000);
- reg = t1_getctl(wc, 0x0028);
- t1_setctl(wc, 0x0028, reg);
-
- /* Set Reset - now with MAGIC TIPS */
- t1_setctl(wc, 0x0048, 0x00000000);
- for (x = 0; x < 10; x++)
- schluffen(&wc->regq);
- /* Clear reset */
- t1_setctl(wc, 0x0048, 0x00010000);
- for (x = 0; x < 10; x++)
- schluffen(&wc->regq);
- /* Switch to caring only about receive interrupts */
- t1_setintmask(wc, 0x00010040);
-}
-
-static void t1_stop_dma(struct t1 *wc)
-{
- /* Disable interrupts and reset */
- unsigned int reg;
-
- /* Disable interrupts */
- t1_setintmask(wc, 0x00000000);
- t1_setctl(wc, 0x0084, 0x00000000);
- t1_setctl(wc, 0x0048, 0x00000000);
- /* Reset the part to be on the safe side */
- reg = t1_getctl(wc, 0x0000);
- reg |= 0x00000001;
- t1_setctl(wc, 0x0000, reg);
-}
-
static void __t1xxp_set_clear(struct t1 *wc, int channo)
{
int i,j;
@@ -678,8 +452,6 @@ static void __t1xxp_set_clear(struct t1 *wc, int channo)
static void t1_release(struct t1 *wc)
{
zt_unregister(&wc->span);
- if (wc->freeregion)
- release_region(wc->iobase, 0xff);
kfree(wc);
printk("Freed a Wildcard TE12xP\n");
}
@@ -1077,8 +849,6 @@ static inline void __t1_check_sigbits(struct t1 *wc)
spin_lock(&wc->reglock);
}
}
- } else {
- debug_printk(1, "no space to request register in isr\n");
}
}
} else if (wc->span.lineconfig & ZT_CONFIG_D4) {
@@ -1241,28 +1011,17 @@ static int t1xxp_close(struct zt_chan *chan)
static int t1xxp_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data)
{
- struct t4_regs regs;
unsigned int x;
struct t1 *wc = chan->pvt;
switch (cmd) {
case WCT4_GET_REGS:
- wc = chan->pvt;
- for (x = 0; x < sizeof(regs.pci) / sizeof(regs.pci[0]); x++)
-#if 1
- regs.pci[x] = (inb(wc->iobase + (x << 2))) |
- (inb(wc->iobase + (x << 2) + 1) << 8) |
- (inb(wc->iobase + (x << 2) + 2) << 16) |
- (inb(wc->iobase + (x << 2) + 3) << 24);
-#else
- regs.pci[x] = (inb(wc->iobase + x));
-#endif
-
- for (x = 0; x < sizeof(regs.regs) / sizeof(regs.regs[0]); x++)
- regs.regs[x] = t1_getreg(wc, x, 0);
-
- if (copy_to_user((struct t4_regs *) data, &regs, sizeof(regs)))
- return -EFAULT;
+ /* Since all register access was moved into the voicebus
+ * module....this was removed. Although...why does the client
+ * library need access to the registers (debugging)? \todo ..
+ */
+ WARN_ON(1);
+ return -ENOSYS;
break;
#ifdef VPM_SUPPORT
case ZT_TONEDETECT:
@@ -1327,6 +1086,9 @@ static int t1xxp_echocan(struct zt_chan *chan, int eclen)
static int t1_software_init(struct t1 *wc)
{
int x;
+ struct pci_dev* dev;
+
+ dev = voicebus_get_pci_dev(wc->vb);
/* Find position */
for (x = 0; x < sizeof(ifaces) / sizeof(ifaces[0]); x++) {
@@ -1344,10 +1106,9 @@ static int t1_software_init(struct t1 *wc)
wc->num = x;
sprintf(wc->span.name, "WCT1/%d", wc->num);
snprintf(wc->span.desc, sizeof(wc->span.desc) - 1, "%s Card %d", wc->variety, wc->num);
-
wc->span.spanconfig = t1xxp_spanconfig;
wc->span.chanconfig = t1xxp_chanconfig;
- wc->span.irq = wc->dev->irq;
+ wc->span.irq = dev->irq;
wc->span.startup = t1xxp_startup;
wc->span.shutdown = t1xxp_shutdown;
wc->span.rbsbits = t1xxp_rbsbits;
@@ -1636,7 +1397,8 @@ static void __t1_do_counters(struct t1 *wc)
static inline void t1_isr_misc(struct t1 *wc)
{
- unsigned int x;
+ const unsigned int x = wc->intcount & 0x3f;
+ int buffer_count = voicebus_current_latency(wc->vb);
if (unlikely(!wc->initialized)) return;
@@ -1644,52 +1406,35 @@ static inline void t1_isr_misc(struct t1 *wc)
__t1_do_counters(wc);
- x = wc->intcount & 0xF;
- switch (x) {
- case 0:
- __t1_check_sigbits_reads(wc);
- break;
- case 1:
- if (!(wc->intcount & 0x30)) {
- __t1_check_alarms_reads(wc);
- wc->alarms_read=1;
- }
- break;
- case 2:
- break;
- case 4:
- break;
- case 5:
- break;
- case 7:
- __t1_check_sigbits(wc);
- break;
- case 8:
- if (wc->alarms_read) {
- __t1_check_alarms(wc);
- wc->alarms_read=0;
- }
- break;
- case 9:
- clean_leftovers(wc);
- break;
+ if ( 0 == x ) {
+ __t1_check_sigbits_reads(wc);
+ }
+ else if ( 1 == x ) {
+ if (!(wc->intcount & 0x30)) {
+ __t1_check_alarms_reads(wc);
+ wc->alarms_read=1;
+ }
+ }
+ else if ( x == buffer_count*2) {
+ __t1_check_sigbits(wc);
+ }
+ else if ( x == (buffer_count*2)+1 ) {
+ if (wc->alarms_read) {
+ __t1_check_alarms(wc);
+ wc->alarms_read=0;
+ }
+ }
+ else if ( x == (buffer_count*2)+2) {
+ clean_leftovers(wc);
}
}
-static inline void t1_transmitprep(struct t1 *wc, int dbl)
+static inline void t1_transmitprep(struct t1 *wc, unsigned char* writechunk)
{
- volatile unsigned char *writechunk;
int x;
int y;
int chan;
- dbl = dbl % 2;
-
- writechunk = (volatile unsigned char *)(wc->writechunk);
- if (dbl)
- /* Write is at interrupt address. Start writing from normal offset */
- writechunk += SFRAME_SIZE;
-
/* Calculate Transmission */
if (likely(wc->initialized)) {
spin_unlock(&wc->reglock);
@@ -1733,17 +1478,11 @@ static inline void cmd_retransmit(struct t1 *wc)
}
}
-static inline void t1_receiveprep(struct t1 *wc, int dbl)
+static inline void t1_receiveprep(struct t1 *wc, unsigned char* readchunk)
{
- volatile unsigned char *readchunk;
int x,chan;
unsigned char expected;
- dbl = dbl % 2;
-
- readchunk = (volatile unsigned char *)wc->readchunk;
- if (dbl)
- readchunk += SFRAME_SIZE;
for (x = 0; x < ZT_CHUNKSIZE; x++) {
if (likely(wc->initialized)) {
for (chan = 0; chan < wc->span.channels; chan++) {
@@ -1758,7 +1497,7 @@ static inline void t1_receiveprep(struct t1 *wc, int dbl)
wc->span.irqmisses++;
cmd_retransmit(wc);
if (unlikely(debug && wc->initialized))
- module_printk("oops: rxident=%d expected=%d\n", wc->rxident, expected);
+ module_printk("oops: rxident=%d expected=%d x=%d\n", wc->rxident, expected, x);
}
}
cmd_decipher(wc, readchunk);
@@ -1785,126 +1524,36 @@ static inline void t1_receiveprep(struct t1 *wc, int dbl)
wake_up_interruptible(&wc->regq);
}
-static inline int t1_check_descriptor(struct t1 *wc, int tx)
-{
- int o2 = 0;
-
- if (!tx) {
- o2 += ERING_SIZE * 4;
- o2 += wc->rdbl * 4;
- } else {
- o2 += wc->tdbl * 4;
- }
-
- if (!(wc->descripchunk[o2] & 0x80000000)) {
- if (tx) {
- wc->txints++;
- t1_transmitprep(wc, wc->tdbl);
- t1_reinit_descriptor(wc, tx, wc->tdbl, "txchk");
- wc->tdbl = (wc->tdbl + 1) % ERING_SIZE;
- wc->intcount++;
- t1_isr_misc(wc);
- } else {
- wc->rxints++;
- t1_receiveprep(wc, wc->rdbl);
- t1_reinit_descriptor(wc, tx, wc->rdbl, "rxchk");
- wc->rdbl = (wc->rdbl + 1) % ERING_SIZE;
- }
- return 1;
- }
- return 0;
-}
-
-static int t1_hardware_init(struct t1 *wc)
+static void
+t1_handle_transmit(void* vbb, void* context)
{
- /* Hardware stuff */
- unsigned int reg;
- unsigned long newjiffies;
-
- /* Initialize descriptors */
- t1_init_descriptors(wc);
-
- /* Enable I/O Access */
- pci_read_config_dword(wc->dev, PCI_COMMAND, &reg);
- reg |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
- pci_write_config_dword(wc->dev, PCI_COMMAND, reg);
- debug_printk(1, "PCI Config reg is %08x\n", reg);
-
- t1_setctl(wc, 0x0000, 0xfff88001);
-
- newjiffies = jiffies + HZ/10;
- while(((reg = t1_getctl(wc,0x0000)) & 0x00000001) && ( time_after(newjiffies,jiffies) ));
- debug_printk(1, "ctlreg 0x0000 now=%08x!\n", reg);
-
- t1_setctl(wc, 0x0000, 0xfff88000);
-
- /* Configure watchdogs, access, etc */
- t1_setctl(wc, 0x0030, 0x00280048);
- t1_setctl(wc, 0x0078, 0x00000013 /* | (1 << 28) */);
-
- reg = t1_getctl(wc, 0x00fc);
- t1_setctl(wc, 0x00fc, (reg & ~0x7) | 0x7); /* normal mode */
- t1_setsdi(wc, 0x00, 0x0100);
- t1_setsdi(wc, 0x16, 0x2100);
- debug_printk(1, "Detected SDI REG0: %08x\n", t1_getsdi(wc, 0x00));
- debug_printk(1, "Detected SDI REG1: %08x\n", t1_getsdi(wc, 0x01));
- debug_printk(1, "Detected SDI REG2: %08x\n", t1_getsdi(wc, 0x02));
-
- reg = t1_getctl(wc, 0x00fc);
- debug_printk(1, "(pre) Reg fc is %08x\n", reg);
-
- t1_setctl(wc, 0x00fc, (reg & ~0x7) | 0x4); /* mac only */
- t1_setsdi(wc, 0x00, 0x0100); /* full duplex */
- t1_setsdi(wc, 0x16, 0x2100);
- reg = t1_getctl(wc, 0x00fc);
- debug_printk(1, "(post) ctlreg 0xfc=%08x\n", reg);
- debug_printk(1, "Detected SDI REG2: %08x\n", t1_getsdi(wc, 0x02));
- debug_printk(1, "ctlreg 0x0088=%08x\n", t1_getctl(wc, 0x0088));
-
- return 0;
+ struct t1* wc = context;
+ /* Either this function is called from within interrupt context, or
+ * the reglock will never be acquired from interrupt context, so it's
+ * safe to grab it without locking interrupt.
+ */
+ memset(vbb, 0, SFRAME_SIZE);
+ spin_lock(&wc->reglock);
+ wc->txints++;
+ t1_transmitprep(wc, vbb);
+ wc->intcount++;
+ t1_isr_misc(wc);
+ spin_unlock(&wc->reglock);
+ voicebus_transmit(wc->vb, vbb);
}
-
-ZAP_IRQ_HANDLER(te12xp_interrupt)
+static void
+t1_handle_receive(void* vbb, void* context)
{
- struct t1 *wc = dev_id;
- unsigned int ints;
- int res;
-
- /* Read interrupts */
+ struct t1* wc = context;
+ wc->rxints++;
+ /* Either this function is called from within interrupt context, or
+ * the reglock will never be acquired from interrupt context, so it's
+ * safe to grab it without locking interrupt.
+ */
spin_lock(&wc->reglock);
- ints = __t1_getctl(wc, 0x0028);
- ints &= 0x3fef; /* Just look at the interrupt conditions */
-
- if (!ints) {
- spin_unlock(&wc->reglock);
-#ifdef LINUX26
- return IRQ_NONE;
-#else
- return;
-#endif
- }
-
- /* clear interrupts interrupts (we only get here if interrupt is for us) */
- __t1_setctl(wc, 0x0028, ints);
-
- if (ints & 0x00000041) {
- do {
- res = t1_check_descriptor(wc, 0);
- res |= t1_check_descriptor(wc, 1);
- } while(res);
- }
- if (ints & 0x0000a3ae) {
- /* This will allow us to recover if interrupts are held for a long period of time */
- debug_printk(1, "Abnormal interrupt %08x detected\n", ints);
- __t1_setctl(wc, 0x0008, 0x00000000);
- __t1_setctl(wc, 0x0010, 0x00000000);
- }
+ t1_receiveprep(wc, vbb);
spin_unlock(&wc->reglock);
-
-#ifdef LINUX26
- return IRQ_RETVAL(1);
-#endif
}
static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -1912,6 +1561,8 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
struct t1 *wc;
struct t1_desc *d = (struct t1_desc *) ent->driver_data;
unsigned int x;
+ int res;
+ int startinglatency;
for (x = 0; x < sizeof(ifaces) / sizeof(ifaces[0]); x++)
if (!ifaces[x]) break;
@@ -1921,9 +1572,7 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
return -EIO;
}
- if (pci_enable_device(pdev))
- return -EIO;
-
+retry:
wc = kmalloc(sizeof(*wc), GFP_KERNEL);
if (!wc)
return -ENOMEM;
@@ -1931,72 +1580,44 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
ifaces[x] = wc;
memset(wc, 0, sizeof(*wc));
spin_lock_init(&wc->reglock);
- wc->iobase = pci_resource_start(pdev, 0);
- wc->dev = pdev;
wc->variety = d->name;
- /* Keep track of whether we need to free the region */
- if (request_region(wc->iobase, 0xff, te12xp_driver.name))
- wc->freeregion = 1;
-
- /* Allocate enough memory for two zt chunks, receive and transmit.
- * Each sample uses 32 bits. Allocate an extra set just for
- * control too */
- wc->writechunk = (int *) pci_alloc_consistent(pdev, PCI_WINDOW_SIZE, &wc->writedma);
- if (!wc->writechunk) {
- module_printk("Unable to allocate DMA-able memory\n");
- if (wc->freeregion)
- release_region(wc->iobase, 0xff);
+ wc->txident = 1;
+
+ init_waitqueue_head(&wc->regq);
+ snprintf(wc->name, sizeof(wc->name)-1, "wcte12xp%d", x);
+ if ((res=voicebus_init(pdev, SFRAME_SIZE, wc->name,
+ t1_handle_receive, t1_handle_transmit, wc, &wc->vb)))
+ {
+ WARN_ON(1);
kfree(wc);
- return -ENOMEM;
+ return res;
}
- wc->readchunk = wc->writechunk + SFRAME_SIZE / 2; /* in doublewords */
- wc->readdma = wc->writedma + SFRAME_SIZE * 2; /* in bytes */
-
- wc->descripchunk = wc->readchunk + SFRAME_SIZE / 2; /* in doublewords */
- wc->descripdma = wc->readdma + SFRAME_SIZE * 2; /* in bytes */
-
- /* Initialize Write/Buffers to all blank data */
- memset((void *)wc->writechunk, 0x00, SFRAME_SIZE * 2);
- memset((void *)wc->readchunk, 0x00, SFRAME_SIZE * 2);
-
- init_waitqueue_head(&wc->regq);
-
- /* Enable bus mastering */
- pci_set_master(pdev);
-
/* Keep track of which device we are */
pci_set_drvdata(pdev, wc);
-
- if (request_irq(pdev->irq, te12xp_interrupt, ZAP_IRQ_SHARED, te12xp_driver.name, wc)) {
- module_printk("Unable to request IRQ %d\n", pdev->irq);
- if (wc->freeregion)
- release_region(wc->iobase, 0xff);
- pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *) wc->writechunk, wc->writedma);
- pci_set_drvdata(pdev, NULL);
- kfree(wc);
- return -EIO;
- }
-
- if (t1_hardware_init(wc)) {
- /* Set Reset Low */
- t1_stop_dma(wc);
- /* Free Resources */
- free_irq(pdev->irq, wc);
- if (wc->freeregion)
- release_region(wc->iobase, 0xff);
- pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *) wc->writechunk, wc->writedma);
- pci_set_drvdata(pdev, NULL);
-
- kfree(wc);
- return -EIO;
-
+ if (VOICEBUS_DEFAULT_LATENCY != latency) {
+ voicebus_set_minlatency(wc->vb, latency);
}
-
- t1_enable_interrupts(wc);
- t1_start_dma(wc);
+ voicebus_start(wc->vb);
+ startinglatency = voicebus_current_latency(wc->vb);
t1_hardware_post_init(wc);
t1_software_init(wc);
+ if (voicebus_current_latency(wc->vb) > startinglatency) {
+ /* The voicebus library increased the latency during
+ * initialization because the host wasn't able to service the
+ * interrupts from the adapter quickly enough. In this case,
+ * we'll increase our latency and restart the initialization.
+ */
+ printk(KERN_NOTICE "%s: Restarting board initialization " \
+ "after increasing latency.\n", wc->name);
+ latency = voicebus_current_latency(wc->vb);
+ zt_unregister(&wc->span);
+ voicebus_release(wc->vb);
+ wc->vb = NULL;
+ kfree(wc);
+ wc = NULL;
+ goto retry;
+ }
module_printk("Found a %s\n", wc->variety);
return 0;
@@ -2021,19 +1642,14 @@ static void __devexit te12xp_remove_one(struct pci_dev *pdev)
destroy_workqueue(vpm150m->wq);
}
#endif
- /* Stop any DMA */
- t1_stop_dma(wc);
-
- /* In case hardware is still there */
- t1_disable_interrupts(wc);
-
+
+ BUG_ON(!wc->vb);
+ voicebus_release(wc->vb);
+ wc->vb = NULL;
+
if (debug && wc->isrreaderrors)
debug_printk(1, "isrreaderrors=%d\n", wc->isrreaderrors);
- /* Immediately free resources */
- free_irq(pdev->irq, wc);
- pci_free_consistent(pdev, PCI_WINDOW_SIZE, (void *)wc->writechunk, wc->writedma);
-
#ifdef VPM_SUPPORT
if(vpm150m) {
spin_lock_irqsave(&wc->reglock, flags);
@@ -2061,7 +1677,7 @@ static struct pci_device_id te12xp_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci, te12xp_pci_tbl);
struct pci_driver te12xp_driver = {
- name: "wcte12x[p]",
+ name: "wcte12xp",
probe: te12xp_init_one,
#ifdef LINUX26
remove: __devexit_p(te12xp_remove_one),
@@ -2094,13 +1710,11 @@ module_param(loopback, int, S_IRUGO | S_IWUSR);
module_param(t1e1override, int, S_IRUGO | S_IWUSR);
module_param(j1mode, int, S_IRUGO | S_IWUSR);
module_param(alarmdebounce, int, S_IRUGO | S_IWUSR);
+module_param(latency, int, S_IRUGO | S_IWUSR);
#ifdef VPM_SUPPORT
module_param(vpmsupport, int, S_IRUGO | S_IWUSR);
module_param(vpmdtmfsupport, int, S_IRUGO | S_IWUSR);
module_param(vpmtsisupport, int, S_IRUGO | S_IWUSR);
-module_param(vpmnlptype, int, S_IRUGO | S_IWUSR);
-module_param(vpmnlpthresh, int, S_IRUGO | S_IWUSR);
-module_param(vpmnlpmaxsupp, int, S_IRUGO | S_IWUSR);
#endif
#else
MODULE_PARM(debug, "i");
diff --git a/wcte12xp/vpmadt032.c b/wcte12xp/vpmadt032.c
index ff8cdde..cdd8e00 100644
--- a/wcte12xp/vpmadt032.c
+++ b/wcte12xp/vpmadt032.c
@@ -35,6 +35,7 @@
#include <linux/list.h>
#include "zaptel.h"
+#include "voicebus.h"
#include "wcte12xp.h"
#include "vpmadt032.h"
@@ -693,6 +694,7 @@ void t1_vpm150m_init(struct t1 *wc) {
extern u8 _binary_vpmadt032_bin_start[];
#else
static const char vpmadt032_firmware[] = "VPMADT032.bin";
+ struct pci_dev* pdev = voicebus_get_pci_dev(wc->vb);
#endif
#if 0
@@ -766,44 +768,6 @@ void t1_vpm150m_init(struct t1 *wc) {
}
debug_printk(1, "Passed\n");
-#if 0
- /* begin short test */
-#define TEST_SIZE 1
- {
- int i;
- unsigned short msg[TEST_SIZE];
-
- set_bit(VPM150M_HPIRESET, &vpm150m->control);
- msleep(2000);
-
- /* lets see whats in there to start with*/
- gpakReadDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg);
- printk("at first :");
- for (i = 0; i< TEST_SIZE; i++)
- printk("%04x ", msg[i]);
- printk("\n");
-
- /* what if we put dead in there*/
- for (i = 0; i< TEST_SIZE; i++)
- msg[i] = 0xdead;
- gpakWriteDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg);
- gpakReadDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg);
- printk("now :");
- for (i = 0; i< TEST_SIZE; i++)
- printk("%04x ", msg[i]);
- printk("\n");
-
- /* lets see if its in there now */
- gpakReadDspMemory(vpm150m->dspid, 0x1000, TEST_SIZE, msg);
- printk("try again:");
- for (i = 0; i< TEST_SIZE; i++)
- printk("%04x ", msg[i]);
- printk("\n");
- }
-
- goto failed_exit;
-#endif
-
#define TEST_SIZE 2
if (debug) {
int i;
@@ -861,51 +825,9 @@ void t1_vpm150m_init(struct t1 *wc) {
printk("%x ", msg[i]);
printk("\n");
}
-#if 0
- printk("Sending\n");
-
- for (i = 0; i < 4; i++) {
- unsigned short x = 0xffff;
- t1_vpm150m_setreg(wc, 1, 0x1000 + i, &x);
- }
-
- gpakReadDspMemory(vpm150m->dspid, 0x1000, 4, imsg);
-
- printk("Read back:\n");
- for (i = 0; i < 4; i++)
- printk("%x ", imsg[i]);
- printk("\n");
-
- printk("Sending\n");
- gpakWriteDspMemory(vpm150m->dspid, 0x1000, 4, omsg);
- for (i = 0; i < 4; i++)
- t1_vpm150m_getreg(wc, 1, 0x1000 + i, &imsg[i]);
- printk("Read back\n");
- for (i = 0; i < 4; i++)
- printk("%x ", imsg[i]);
- printk("\n");
-
-#endif
-
-#if 0
- /* Load the firmware */
- set_bit(VPM150M_SPIRESET, &vpm150m->control);
-
- /* Wait for it to boot */
- msleep(7000);
-
- pingstatus = gpakPingDsp(vpm150m->dspid, &version);
-
- if (pingstatus) {
- module_printk("Pingstatus %d, you failed!!! Ha ha ha ha\n", pingstatus);
- } else
- module_printk("version is 0x%08x\n", version);
-
- if (pingstatus || (version != 0x106)) {
-#endif
#if defined(HOTPLUG_FIRMWARE)
- if ((request_firmware(&firmware, vpmadt032_firmware, &wc->dev->dev) != 0) ||
+ if ((request_firmware(&firmware, vpmadt032_firmware, &pdev->dev) != 0) ||
!firmware) {
printk("VPMADT032: firmware %s not available from userspace\n", vpmadt032_firmware);
goto failed_exit;
diff --git a/wcte12xp/wcte12xp.h b/wcte12xp/wcte12xp.h
index 2edc109..5aeb940 100644
--- a/wcte12xp/wcte12xp.h
+++ b/wcte12xp/wcte12xp.h
@@ -52,9 +52,8 @@
#define PCI_WINDOW_SIZE ((2 * 2 * 2 * SFRAME_SIZE) + (2 * ERING_SIZE * 4))
-#define MAX_COMMANDS 7*7*2 /* 42 bytes /3 (cntl,addr,data) /2 (cs) */
+#define MAX_COMMANDS 7*7*2*2 /* 42 bytes /3 (cntl,addr,data) /2 (cs) */
-#define ISR_COMMANDS 2
#define NUM_EC 4
#define __CMD_VPM (1 << 16) /* flag for VPM action */
@@ -104,13 +103,11 @@ struct command {
struct cmdq {
struct command cmds[MAX_COMMANDS];
- unsigned char isrshadow[ISR_COMMANDS];
};
struct vpm150m;
struct t1 {
- struct pci_dev *dev;
spinlock_t reglock;
unsigned char txident;
unsigned char rxident;
@@ -125,6 +122,7 @@ struct t1 {
int alarmcount; /* How much red alarm we've seen */
int alarmdebounce;
char *variety;
+ char name[80];
unsigned int intcount;
int sync;
int dead;
@@ -139,29 +137,18 @@ struct t1 {
int initialized;
int *chanmap;
unsigned char ledtestreg;
- unsigned long iobase;
unsigned char ec_chunk1[32][ZT_CHUNKSIZE];
unsigned char ec_chunk2[32][ZT_CHUNKSIZE];
struct zt_span span; /* Span */
struct zt_chan chans[32]; /* Channels */
- int freeregion;
- unsigned int intmask;
wait_queue_head_t regq;
struct cmdq cmdq;
struct command dummy; /* preallocate for dummy noop command */
unsigned char ctlreg;
- int rdbl;
- int tdbl;
unsigned int rxints;
unsigned int txints;
- unsigned int sdi;
int usecount;
- dma_addr_t readdma;
- dma_addr_t writedma;
- dma_addr_t descripdma;
- volatile unsigned int *writechunk;
- volatile unsigned int *readchunk;
- volatile unsigned int *descripchunk;
+ struct voicebus* vb;
unsigned int isrreaderrors;
#ifdef VPM_SUPPORT
int vpm;