summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrussell <russell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-07-25 14:42:56 +0000
committerrussell <russell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2005-07-25 14:42:56 +0000
commitc077a139b523bc15aae6526be1252d1f56befb0b (patch)
tree835eadf40a746fdff545cc846cbfe3915ddf37cd
parent587873e3cafb1ef25df05b5e239e065818e03004 (diff)
add support for dual span cards
git-svn-id: http://svn.digium.com/svn/zaptel/branches/v1-0@704 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-xMakefile8
-rwxr-xr-xwct4xxp.c222
2 files changed, 135 insertions, 95 deletions
diff --git a/Makefile b/Makefile
index 993a0fb..c1a86de 100755
--- a/Makefile
+++ b/Makefile
@@ -270,7 +270,6 @@ install: all devices
install -D -m 755 sethdlc $(INSTALL_PREFIX)/sbin/sethdlc ; \
fi
if [ -f zttool ]; then install -D -m 755 zttool $(INSTALL_PREFIX)/sbin/zttool; fi
-
if [ -f zaptel.ko ]; then \
for x in $(MODULESKO) ztdummy.ko; do \
install -D -m 644 $$x $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/$$x ; \
@@ -286,7 +285,6 @@ install: all devices
rm -f $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/wcfxsusb.ko; \
fi; \
fi
-
install -D -m 755 $(LIBTONEZONE) $(INSTALL_PREFIX)/usr/lib/$(LIBTONEZONE)
if [ -x /usr/sbin/sestatus ] && (/usr/sbin/sestatus | grep "SELinux status:" | grep -q "enabled") ; then restorecon -v $(INSTALL_PREFIX)/usr/lib/$(LIBTONEZONE); fi
install -D -m 644 zaptel.h $(INSTALL_PREFIX)/usr/include/linux/zaptel.h
@@ -318,8 +316,10 @@ install: all devices
done
if ! grep "alias wctdm" $(MODCONF); then \
echo "alias wctdm wcfxs" >> $(MODCONF); \
- fi \
-
+ fi
+ if ! grep "alias wct2xxp" $(MODCONF); then \
+ echo "alias wct2xxp wct4xxp" >> $(MODCONF); \
+ fi
if [ -d /etc/modutils ]; then \
/sbin/update-modules ; \
fi
diff --git a/wct4xxp.c b/wct4xxp.c
index c81b0ae..e951197 100755
--- a/wct4xxp.c
+++ b/wct4xxp.c
@@ -56,7 +56,7 @@
/* Work queues are a way to better distribute load on SMP systems */
#ifdef LINUX26
-#define ENABLE_WORKQUEUES
+#define ENABLE_WORKQUEUES
#endif
/* Enable prefetching may help performance */
@@ -192,6 +192,7 @@ static int altab[] = {
#define TYPE_J1 3 /* is a running J1 */
#define FLAG_2NDGEN (1 << 3)
+#define FLAG_2PORT (1 << 4)
#define CANARY 0xc0de
@@ -203,6 +204,8 @@ struct devtype {
static struct devtype wct4xxp = { "Wildcard TE410P/TE405P (1st Gen)", 0 };
static struct devtype wct410p2 = { "Wildcard TE410P (2nd Gen)", FLAG_2NDGEN };
static struct devtype wct405p2 = { "Wildcard TE405P (2nd Gen)", FLAG_2NDGEN };
+static struct devtype wct205 = { "Wildcard TE205P ", FLAG_2NDGEN | FLAG_2PORT };
+static struct devtype wct210 = { "Wildcard TE210P ", FLAG_2NDGEN | FLAG_2PORT };
static int inirq = 0;
@@ -256,6 +259,7 @@ struct t4 {
int globalconfig; /* Whether global setup has been done */
int syncsrc; /* active sync source */
struct t4_span *tspans[4]; /* Individual spans */
+ int numspans; /* Number of spans on the card */
#ifdef VPM_SUPPORT
int vpm;
#endif
@@ -562,6 +566,10 @@ static void __t4_check_vpm(struct t4 *wc, unsigned int newio)
energy = ZT_XLAW(energy, ts->chans);
ts->dtmfactive |= (1 << base);
ts->dtmfenergy[base] = energy;
+ if (ts->dtmfdigit[base]) {
+ if (ts->dtmfmask & (1 << base))
+ zt_qevent_lock(&ts->span.chans[base], (ZT_EVENT_DTMFUP | ts->dtmfdigit[base]));
+ }
ts->dtmfdigit[base] = digit;
if (ts->dtmfdigit[base]) {
if (ts->dtmfmask & (1 << base))
@@ -774,7 +782,7 @@ static int t4_maint(struct zt_span *span, int cmd)
printk("XXX Stop sending loop codes E1 XXX\n");
break;
default:
- printk("TE410P: Unknown E1 maint command: %d\n", cmd);
+ printk("TE%dXXP: Unknown E1 maint command: %d\n", wc->numspans, cmd);
break;
}
} else {
@@ -798,7 +806,7 @@ static int t4_maint(struct zt_span *span, int cmd)
t4_framer_out(wc, span->offset, 0x21, 0x40); /* FMR5: Nothing but RBS mode */
break;
default:
- printk("TE410P: Unknown T1 maint command: %d\n", cmd);
+ printk("TE%dXXP: Unknown T1 maint command: %d\n", wc->numspans, cmd);
break;
}
}
@@ -869,7 +877,7 @@ static int t4_shutdown(struct zt_span *span)
tspan = span->offset + 1;
if (tspan < 0) {
- printk("T4XXP: Span '%d' isn't us?\n", span->spanno);
+ printk("T%dXXP: Span '%d' isn't us?\n", wc->numspans, span->spanno);
return -1;
}
@@ -880,12 +888,17 @@ static int t4_shutdown(struct zt_span *span)
if (wasrunning)
wc->spansstarted--;
__t4_set_led(wc, span->offset, WC_OFF);
- if ((!(wc->tspans[0]->span.flags & ZT_FLAG_RUNNING)) &&
+ if (((wc->numspans == 4) &&
+ (!(wc->tspans[0]->span.flags & ZT_FLAG_RUNNING)) &&
(!(wc->tspans[1]->span.flags & ZT_FLAG_RUNNING)) &&
(!(wc->tspans[2]->span.flags & ZT_FLAG_RUNNING)) &&
- (!(wc->tspans[3]->span.flags & ZT_FLAG_RUNNING))) {
+ (!(wc->tspans[3]->span.flags & ZT_FLAG_RUNNING)))
+ ||
+ ((wc->numspans == 2) &&
+ (!(wc->tspans[0]->span.flags & ZT_FLAG_RUNNING)) &&
+ (!(wc->tspans[1]->span.flags & ZT_FLAG_RUNNING)))) {
/* No longer in use, disable interrupts */
- printk("TE410P: Disabling interrupts since there are no active spans\n");
+ printk("TE%dXXP: Disabling interrupts since there are no active spans\n", wc->numspans);
wc->dmactrl = 0x0;
__t4_pci_out(wc, WC_DMACTRL, 0x00000000);
/* Acknowledge any pending interrupts */
@@ -906,7 +919,7 @@ static int t4_spanconfig(struct zt_span *span, struct zt_lineconfig *lc)
printk("About to enter spanconfig!\n");
if (debug & DEBUG_MAIN)
- printk("TE410P: Configuring span %d\n", span->spanno);
+ printk("TE%dXXP: Configuring span %d\n", wc->numspans, span->spanno);
/* XXX We assume lineconfig is okay and shouldn't XXX */
span->lineconfig = lc->lineconfig;
span->txlevel = lc->lbo;
@@ -917,7 +930,7 @@ static int t4_spanconfig(struct zt_span *span, struct zt_lineconfig *lc)
lc->sync = 0;
/* remove this span number from the current sync sources, if there */
- for(i = 0; i < 4; i++) {
+ for(i = 0; i < wc->numspans; i++) {
if (wc->tspans[i]->sync == span->spanno) {
wc->tspans[i]->sync = 0;
wc->tspans[i]->psync = 0;
@@ -946,9 +959,9 @@ static int t4_chanconfig(struct zt_chan *chan, int sigtype)
alreadyrunning = wc->tspans[chan->span->offset]->span.flags & ZT_FLAG_RUNNING;
if (debug & DEBUG_MAIN) {
if (alreadyrunning)
- printk("TE410P: Reconfigured channel %d (%s) sigtype %d\n", chan->channo, chan->name, sigtype);
+ printk("TE%dXXP: Reconfigured channel %d (%s) sigtype %d\n", wc->numspans, chan->channo, chan->name, sigtype);
else
- printk("TE410P: Configured channel %d (%s) sigtype %d\n", chan->channo, chan->name, sigtype);
+ printk("TE%dXXP: Configured channel %d (%s) sigtype %d\n", wc->numspans, chan->channo, chan->name, sigtype);
}
spin_lock_irqsave(&wc->reglock, flags);
if (alreadyrunning)
@@ -988,11 +1001,11 @@ static void init_spans(struct t4 *wc)
gen2 = (wc->tspans[0]->spanflags & FLAG_2NDGEN);
if (!wc->t1e1)
offset += 4;
- for (x=0;x<4;x++) {
+ for (x=0;x<wc->numspans;x++) {
ts = wc->tspans[x];
- sprintf(ts->span.name, "TE4/%d/%d",
+ sprintf(ts->span.name, "TE%d/%d/%d", wc->numspans,
wc->num, x + 1);
- sprintf(ts->span.desc, "TE410P (PCI) Card %d Span %d", wc->num, x+1);
+ sprintf(ts->span.desc, "T%dXXP (PCI) Card %d Span %d", wc->numspans, wc->num, x+1);
ts->span.spanconfig = t4_spanconfig;
ts->span.chanconfig = t4_chanconfig;
ts->span.startup = t4_startup;
@@ -1026,7 +1039,7 @@ static void init_spans(struct t4 *wc)
init_waitqueue_head(&ts->span.maintq);
for (y=0;y<wc->tspans[x]->span.channels;y++) {
struct zt_chan *mychans = ts->chans + y;
- sprintf(mychans->name, "TE4/%d/%d/%d", wc->num, x + 1, y + 1);
+ sprintf(mychans->name, "TE%d/%d/%d/%d", wc->numspans, wc->num, x + 1, y + 1);
mychans->sigcap = ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_FXSLS | ZT_SIG_FXSGS | ZT_SIG_FXSKS |
ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_FXOKS | ZT_SIG_CAS | ZT_SIG_EM_E1 | ZT_SIG_DACS_RBS;
c = (x * ts->span.channels) + y;
@@ -1044,7 +1057,7 @@ static void t4_serial_setup(struct t4 *wc, int unit)
{
if (!wc->globalconfig) {
wc->globalconfig = 1;
- printk("TE410P: Setting up global serial parameters\n");
+ printk("TE%dXXP: Setting up global serial parameters\n", wc->numspans);
t4_framer_out(wc, 0, 0x85, 0xe0); /* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from channel 0 */
t4_framer_out(wc, 0, 0x08, 0x01); /* IPC: Interrupt push/pull active low */
@@ -1100,12 +1113,12 @@ static void __t4_set_timing_source(struct t4 *wc, int unit)
timing = 0x34; /* CMR1: RCLK unit, 8.192 Mhz TCLK, RCLK is 8.192 Mhz */
if ((unit > -1) && (unit < 4)) {
timing |= (unit << 6);
- for (x=0;x<4;x++) /* set all 4 receive reference clocks to unit */
+ for (x=0;x<wc->numspans;x++) /* set all 4 receive reference clocks to unit */
__t4_framer_out(wc, x, 0x44, timing);
wc->dmactrl |= (1 << 29);
__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
} else {
- for (x=0;x<4;x++) /* set each receive reference clock to itself */
+ for (x=0;x<wc->numspans;x++) /* set each receive reference clock to itself */
__t4_framer_out(wc, x, 0x44, timing | (x << 6));
wc->dmactrl &= ~(1 << 29);
__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
@@ -1115,11 +1128,11 @@ static void __t4_set_timing_source(struct t4 *wc, int unit)
unit = 0;
else
unit++;
- for (x=0;x<4;x++)
+ for (x=0;x<wc->numspans;x++)
wc->tspans[x]->span.syncsrc = unit;
} else {
if (debug & DEBUG_MAIN)
- printk("TE410P: Timing source already set to %d\n", unit);
+ printk("TE%dXXP: Timing source already set to %d\n", wc->numspans, unit);
}
#if 0
printk("wct4xxp: Timing source set to %d\n",unit);
@@ -1130,7 +1143,7 @@ static void __t4_set_timing_source_auto(struct t4 *wc)
{
int x;
wc->checktiming = 0;
- for (x=0;x<4;x++) {
+ for (x=0;x<wc->numspans;x++) {
if (wc->tspans[x]->sync) {
if ((wc->tspans[wc->tspans[x]->psync - 1]->span.flags & ZT_FLAG_RUNNING) &&
!(wc->tspans[wc->tspans[x]->psync - 1]->span.alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE) )) {
@@ -1232,7 +1245,7 @@ static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlev
__t4_check_sigbits(wc, unit);
}
- printk("TE410P: Span %d configured for %s/%s\n", unit + 1, framing, line);
+ printk("TE%dXXP: Span %d configured for %s/%s\n", wc->numspans, unit + 1, framing, line);
}
static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig)
@@ -1318,7 +1331,7 @@ static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig)
__t4_check_alarms(wc, unit);
__t4_check_sigbits(wc, unit);
}
- printk("TE410P: Span %d configured for %s/%s%s\n", unit + 1, framing, line, crc4);
+ printk("TE%dXXP: Span %d configured for %s/%s%s\n", wc->numspans, unit + 1, framing, line, crc4);
}
static int t4_startup(struct zt_span *span)
@@ -1335,7 +1348,7 @@ static int t4_startup(struct zt_span *span)
printk("About to enter startup!\n");
tspan = span->offset + 1;
if (tspan < 0) {
- printk("TE410P: Span '%d' isn't us?\n", span->spanno);
+ printk("TE%dXXP: Span '%d' isn't us?\n", wc->numspans, span->spanno);
return -1;
}
@@ -1394,8 +1407,10 @@ static int t4_startup(struct zt_span *span)
spin_unlock_irqrestore(&wc->reglock, flags);
if (wc->tspans[0]->sync == span->spanno) printk("SPAN %d: Primary Sync Source\n",span->spanno);
if (wc->tspans[1]->sync == span->spanno) printk("SPAN %d: Secondary Sync Source\n",span->spanno);
- if (wc->tspans[2]->sync == span->spanno) printk("SPAN %d: Tertiary Sync Source\n",span->spanno);
- if (wc->tspans[3]->sync == span->spanno) printk("SPAN %d: Quaternary Sync Source\n",span->spanno);
+ if (wc->numspans == 4) {
+ if (wc->tspans[2]->sync == span->spanno) printk("SPAN %d: Tertiary Sync Source\n",span->spanno);
+ if (wc->tspans[3]->sync == span->spanno) printk("SPAN %d: Quaternary Sync Source\n",span->spanno);
+ }
#ifdef VPM_SUPPORT
if (!alreadyrunning && !wc->vpm) {
wait_a_little();
@@ -1421,7 +1436,9 @@ static inline void e1_check(struct t4 *wc, int span, int val)
if (ts->e1check > 100) {
/* Wait 1000 ms */
wc->e1recover = 1000 * 8;
- wc->tspans[0]->e1check = wc->tspans[1]->e1check = wc->tspans[2]->e1check = wc->tspans[3]->e1check = 0;
+ wc->tspans[0]->e1check = wc->tspans[1]->e1check = 0;
+ if (wc->numspans == 4)
+ wc->tspans[2]->e1check = wc->tspans[3]->e1check = 0;
if (debug & DEBUG_MAIN)
printk("Detected loss of E1 alignment on span %d!\n", span);
t4_reset_dma(wc);
@@ -1451,17 +1468,19 @@ static void t4_receiveprep(struct t4 *wc, int irq)
wc->last0 = 1;
}
if (dbl) {
- for (x=0;x<4;x++)
+ for (x=0;x<wc->numspans;x++)
wc->tspans[x]->irqmisses++;
if (debug & DEBUG_MAIN)
- printk("TE410P: Double/missed interrupt detected\n");
+ printk("TE%dXXP: Double/missed interrupt detected\n", wc->numspans);
}
for (x=0;x<ZT_CHUNKSIZE;x++) {
for (z=0;z<24;z++) {
/* All T1/E1 channels */
tmp = readchunk[z+1+offset];
- wc->tspans[3]->span.chans[z].readchunk[x] = tmp & 0xff;
- wc->tspans[2]->span.chans[z].readchunk[x] = (tmp & 0xff00) >> 8;
+ if (wc->numspans == 4) {
+ wc->tspans[3]->span.chans[z].readchunk[x] = tmp & 0xff;
+ wc->tspans[2]->span.chans[z].readchunk[x] = (tmp & 0xff00) >> 8;
+ }
wc->tspans[1]->span.chans[z].readchunk[x] = (tmp & 0xff0000) >> 16;
wc->tspans[0]->span.chans[z].readchunk[x] = tmp >> 24;
}
@@ -1469,17 +1488,21 @@ static void t4_receiveprep(struct t4 *wc, int irq)
if (wc->e1recover > 0)
wc->e1recover--;
tmp = readchunk[0];
- e1_check(wc, 3, (tmp & 0x7f));
- e1_check(wc, 2, (tmp & 0x7f00) >> 8);
+ if (wc->numspans == 4) {
+ e1_check(wc, 3, (tmp & 0x7f));
+ e1_check(wc, 2, (tmp & 0x7f00) >> 8);
+ }
e1_check(wc, 1, (tmp & 0x7f0000) >> 16);
e1_check(wc, 0, (tmp & 0x7f000000) >> 24);
for (z=24;z<31;z++) {
/* Only E1 channels now */
tmp = readchunk[z+1];
- if (wc->tspans[3]->span.channels > 24)
- wc->tspans[3]->span.chans[z].readchunk[x] = tmp & 0xff;
- if (wc->tspans[2]->span.channels > 24)
- wc->tspans[2]->span.chans[z].readchunk[x] = (tmp & 0xff00) >> 8;
+ if (wc->numspans == 4) {
+ if (wc->tspans[3]->span.channels > 24)
+ wc->tspans[3]->span.chans[z].readchunk[x] = tmp & 0xff;
+ if (wc->tspans[2]->span.channels > 24)
+ wc->tspans[2]->span.chans[z].readchunk[x] = (tmp & 0xff00) >> 8;
+ }
if (wc->tspans[1]->span.channels > 24)
wc->tspans[1]->span.chans[z].readchunk[x] = (tmp & 0xff0000) >> 16;
if (wc->tspans[0]->span.channels > 24)
@@ -1489,7 +1512,7 @@ static void t4_receiveprep(struct t4 *wc, int irq)
/* Advance pointer by 4 TDM frame lengths */
readchunk += 32;
}
- for (x=0;x<4;x++) {
+ for (x=0;x<wc->numspans;x++) {
if (wc->tspans[x]->span.flags & ZT_FLAG_RUNNING) {
for (y=0;y<wc->tspans[x]->span.channels;y++) {
/* Echo cancel double buffered data */
@@ -1570,7 +1593,7 @@ static void workq_handlespan(void *data)
static void t4_prep_gen2(struct t4 *wc)
{
int x;
- for (x=0;x<4;x++) {
+ for (x=0;x<wc->numspans;x++) {
if (wc->tspans[x]->span.flags & ZT_FLAG_RUNNING) {
__receive_span(wc->tspans[x]);
__transmit_span(wc->tspans[x]);
@@ -1594,7 +1617,7 @@ static void t4_transmitprep(struct t4 *wc, int irq)
} else {
writechunk = wc->writechunk + ZT_CHUNKSIZE * 32 + 1;
}
- for (y=0;y<4;y++) {
+ for (y=0;y<wc->numspans;y++) {
if (wc->tspans[y]->span.flags & ZT_FLAG_RUNNING)
zt_transmit(&wc->tspans[y]->span);
}
@@ -1613,10 +1636,12 @@ static void t4_transmitprep(struct t4 *wc, int irq)
for (z=24;z<31;z++) {
/* Only E1 channels now */
tmp = 0;
- if (wc->tspans[3]->span.channels > 24)
- tmp |= wc->tspans[3]->span.chans[z].writechunk[x];
- if (wc->tspans[2]->span.channels > 24)
- tmp |= (wc->tspans[2]->span.chans[z].writechunk[x] << 8);
+ if (wc->numspans == 4) {
+ if (wc->tspans[3]->span.channels > 24)
+ tmp |= wc->tspans[3]->span.chans[z].writechunk[x];
+ if (wc->tspans[2]->span.channels > 24)
+ tmp |= (wc->tspans[2]->span.chans[z].writechunk[x] << 8);
+ }
if (wc->tspans[1]->span.channels > 24)
tmp |= (wc->tspans[1]->span.chans[z].writechunk[x] << 16);
if (wc->tspans[0]->span.channels > 24)
@@ -1798,7 +1823,7 @@ static void __t4_check_alarms(struct t4 *wc, int span)
if (alarms && !(ts->spanflags & FLAG_SENDINGYELLOW)) {
unsigned char fmr4;
#if 1
- printk("wct4xxp: Setting yellow alarm on span %d\n", span + 1);
+ printk("wct%dxxp: Setting yellow alarm on span %d\n", wc->numspans, span + 1);
#endif
/* We manually do yellow alarm to handle RECOVER and NOTOPEN, otherwise it's auto anyway */
fmr4 = __t4_framer_in(wc, span, 0x20);
@@ -1807,7 +1832,7 @@ static void __t4_check_alarms(struct t4 *wc, int span)
} else if ((!alarms) && (ts->spanflags & FLAG_SENDINGYELLOW)) {
unsigned char fmr4;
#if 1
- printk("wct4xxp: Clearing yellow alarm on span %d\n", span + 1);
+ printk("wct%dxxp: Clearing yellow alarm on span %d\n", wc->numspans, span + 1);
#endif
/* We manually do yellow alarm to handle RECOVER */
fmr4 = __t4_framer_in(wc, span, 0x20);
@@ -1828,7 +1853,7 @@ static void __t4_check_alarms(struct t4 *wc, int span)
static void __t4_do_counters(struct t4 *wc)
{
int span;
- for (span=0;span<4;span++) {
+ for (span=0;span<wc->numspans;span++) {
struct t4_span *ts = wc->tspans[span];
if (ts->alarmtimer) {
if (!--ts->alarmtimer) {
@@ -1846,7 +1871,7 @@ static inline void __handle_leds(struct t4 *wc)
int x;
wc->blinktimer++;
- for (x=0;x<4;x++) {
+ for (x=0;x<wc->numspans;x++) {
struct t4_span *ts = wc->tspans[x];
if (ts->span.flags & ZT_FLAG_RUNNING) {
if (ts->span.alarms & (ZT_ALARM_RED | ZT_ALARM_BLUE)) {
@@ -2047,17 +2072,17 @@ static inline void __t4_framer_interrupt(struct t4 *wc, int span)
}
if (debugslips && !ts->span.alarms) {
if (isr3 & 0x02)
- printk("TE410P: RECEIVE slip NEGATIVE on span %d\n", span + 1);
+ printk("TE%d10P: RECEIVE slip NEGATIVE on span %d\n", wc->numspans, span + 1);
if (isr3 & 0x01)
- printk("TE410P: RECEIVE slip POSITIVE on span %d\n", span + 1);
+ printk("TE%d10P: RECEIVE slip POSITIVE on span %d\n", wc->numspans, span + 1);
if (gis & 0x10)
isr4 = __t4_framer_in(wc, span, 0x6c);
else
isr4 = 0;
if (isr4 & 0x80)
- printk("TE410P: TRANSMIT slip POSITIVE on span %d\n", span + 1);
+ printk("TE%dXXP: TRANSMIT slip POSITIVE on span %d\n", wc->numspans, span + 1);
if (isr4 & 0x40)
- printk("TE410P: TRANSMIT slip NEGATIVE on span %d\n", span + 1);
+ printk("TE%d10P: TRANSMIT slip NEGATIVE on span %d\n", wc->numspans, span + 1);
}
}
@@ -2115,7 +2140,7 @@ static void t4_interrupt_gen2(int irq, void *dev_id, struct pt_regs *regs)
if (status & 0x2) {
#ifdef ENABLE_WORKQUEUES
int cpus = num_online_cpus();
- atomic_set(&wc->worklist, 4);
+ atomic_set(&wc->worklist, wc->numspans);
if (wc->tspans[0]->span.flags & ZT_FLAG_RUNNING)
t4_queue_work(wc->workq, &wc->tspans[0]->swork, 0);
else
@@ -2124,14 +2149,16 @@ static void t4_interrupt_gen2(int irq, void *dev_id, struct pt_regs *regs)
t4_queue_work(wc->workq, &wc->tspans[1]->swork, 1 % cpus);
else
atomic_dec(&wc->worklist);
- if (wc->tspans[2]->span.flags & ZT_FLAG_RUNNING)
- t4_queue_work(wc->workq, &wc->tspans[2]->swork, 2 % cpus);
- else
- atomic_dec(&wc->worklist);
- if (wc->tspans[3]->span.flags & ZT_FLAG_RUNNING)
- t4_queue_work(wc->workq, &wc->tspans[3]->swork, 3 % cpus);
- else
- atomic_dec(&wc->worklist);
+ if (wc->numspans == 4) {
+ if (wc->tspans[2]->span.flags & ZT_FLAG_RUNNING)
+ t4_queue_work(wc->workq, &wc->tspans[2]->swork, 2 % cpus);
+ else
+ atomic_dec(&wc->worklist);
+ if (wc->tspans[3]->span.flags & ZT_FLAG_RUNNING)
+ t4_queue_work(wc->workq, &wc->tspans[3]->swork, 3 % cpus);
+ else
+ atomic_dec(&wc->worklist);
+ }
#else
t4_prep_gen2(wc);
#endif
@@ -2423,9 +2450,9 @@ static int t4_hardware_init_1(struct t4 *wc, int gen2)
unsigned int version;
version = t4_pci_in(wc, WC_VERSION);
- printk("TE410P version %08x, burst %s, slip debug: %s\n", version, noburst ? "OFF" : "ON", debugslips ? "ON" : "OFF");
+ printk("TE%dXXP version %08x, burst %s, slip debug: %s\n", wc->numspans, version, noburst ? "OFF" : "ON", debugslips ? "ON" : "OFF");
#ifdef ENABLE_WORKQUEUES
- printk("TE410P running with work queues.\n");
+ printk("TE%dXXP running with work queues.\n", wc->numspans);
#endif
/* Make sure DMA engine is not running and interrupts are acknowledged */
@@ -2481,10 +2508,10 @@ static int __devinit t4_launch(struct t4 *wc)
unsigned long flags;
if (wc->tspans[0]->span.flags & ZT_FLAG_REGISTERED)
return 0;
- printk("TE410P: Launching card: %d\n", wc->order);
+ printk("TE%dXXP: Launching card: %d\n", wc->numspans, wc->order);
/* Setup serial parameters and system interface */
- for (x=0;x<4;x++)
+ for (x=0;x<wc->numspans;x++)
t4_serial_setup(wc, x);
if (zt_register(&wc->tspans[0]->span, 0)) {
@@ -2496,18 +2523,21 @@ static int __devinit t4_launch(struct t4 *wc)
zt_unregister(&wc->tspans[0]->span);
return -1;
}
- if (zt_register(&wc->tspans[2]->span, 0)) {
- printk(KERN_ERR "Unable to register span %s\n", wc->tspans[2]->span.name);
- zt_unregister(&wc->tspans[0]->span);
- zt_unregister(&wc->tspans[1]->span);
- return -1;
- }
- if (zt_register(&wc->tspans[3]->span, 0)) {
- printk(KERN_ERR "Unable to register span %s\n", wc->tspans[3]->span.name);
- zt_unregister(&wc->tspans[0]->span);
- zt_unregister(&wc->tspans[1]->span);
- zt_unregister(&wc->tspans[2]->span);
- return -1;
+
+ if (wc->numspans == 4) {
+ if (zt_register(&wc->tspans[2]->span, 0)) {
+ printk(KERN_ERR "Unable to register span %s\n", wc->tspans[2]->span.name);
+ zt_unregister(&wc->tspans[0]->span);
+ zt_unregister(&wc->tspans[1]->span);
+ return -1;
+ }
+ if (zt_register(&wc->tspans[3]->span, 0)) {
+ printk(KERN_ERR "Unable to register span %s\n", wc->tspans[3]->span.name);
+ zt_unregister(&wc->tspans[0]->span);
+ zt_unregister(&wc->tspans[1]->span);
+ zt_unregister(&wc->tspans[2]->span);
+ return -1;
+ }
}
wc->checktiming = 1;
spin_lock_irqsave(&wc->reglock, flags);
@@ -2544,6 +2574,12 @@ static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_i
basesize = ZT_MAX_CHUNKSIZE * 32 * 4;
else
basesize = ZT_MAX_CHUNKSIZE * 32 * 2 * 4;
+
+ if (dt->flags & FLAG_2PORT)
+ wc->numspans = 2;
+ else
+ wc->numspans = 4;
+
wc->variety = dt->desc;
wc->memaddr = pci_resource_start(pdev, 0);
@@ -2556,9 +2592,9 @@ static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_i
printk("wct4: Unable to request memory region :(, using anyway...\n");
#endif
if (pci_request_regions(pdev, wc->variety))
- printk("wct4xxp: Unable to request regions\n");
+ printk("wct%dxxp: Unable to request regions\n", wc->numspans);
- printk("Found TE410P at base address %08lx, remapped to %p\n", wc->memaddr, wc->membase);
+ printk("Found TE%dXXP at base address %08lx, remapped to %p\n", wc->numspans, wc->memaddr, wc->membase);
wc->dev = pdev;
@@ -2566,7 +2602,7 @@ static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_i
/* 32 channels, Double-buffer, Read/Write, 4 spans */
(unsigned int *)pci_alloc_consistent(pdev, basesize * 2, &wc->writedma);
if (!wc->writechunk) {
- printk("wct4xxp: Unable to allocate DMA-able memory\n");
+ printk("wct%dxxp: Unable to allocate DMA-able memory\n", wc->numspans);
return -ENOMEM;
}
@@ -2611,13 +2647,13 @@ static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_i
#ifdef ENABLE_WORKQUEUES
if (dt->flags & FLAG_2NDGEN) {
char tmp[20];
- sprintf(tmp, "te4xxp[%d]", wc->num);
+ sprintf(tmp, "te%dxxp[%d]", wc->numspans, wc->num);
wc->workq = create_workqueue(tmp);
}
#endif
/* Allocate pieces we need here */
- for (x=0;x<4;x++) {
+ for (x=0;x<wc->numspans;x++) {
if (wc->t1e1 & (1 << x)) {
wc->tspans[x] = kmalloc(sizeof(struct t4_span) + sizeof(struct zt_chan) * 31, GFP_KERNEL);
if (wc->tspans[x]) {
@@ -2648,7 +2684,7 @@ static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_i
#ifdef SUPPORT_GEN1
- if (request_irq(pdev->irq, (dt->flags & FLAG_2NDGEN) ? t4_interrupt_gen2 :t4_interrupt, SA_INTERRUPT | SA_SHIRQ, "t4xxp", wc))
+ if (request_irq(pdev->irq, (dt->flags & FLAG_2NDGEN) ? t4_interrupt_gen2 :t4_interrupt, SA_INTERRUPT | SA_SHIRQ, (wc->numspans == 2) ? "wct2xxp" : "wct4xxp", wc))
#else
if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN)) {
printk("This driver does not support 1st gen modules\n");
@@ -2715,7 +2751,7 @@ static int t4_hardware_stop(struct t4 *wc)
t4_pci_out(wc, WC_GPIO, 0x0000000);
t4_pci_out(wc, WC_LEDS, 0x00000000);
- printk("\nStopped TE410P, Turned off DMA\n");
+ printk("\nStopped TE%dXXP, Turned off DMA\n", wc->numspans);
return 0;
}
@@ -2732,10 +2768,12 @@ static void __devexit t4_remove_one(struct pci_dev *pdev)
zt_unregister(&wc->tspans[0]->span);
if (wc->tspans[1]->span.flags & ZT_FLAG_REGISTERED)
zt_unregister(&wc->tspans[1]->span);
- if (wc->tspans[2]->span.flags & ZT_FLAG_REGISTERED)
- zt_unregister(&wc->tspans[2]->span);
- if (wc->tspans[3]->span.flags & ZT_FLAG_REGISTERED)
- zt_unregister(&wc->tspans[3]->span);
+ if (wc->numspans == 4) {
+ if (wc->tspans[2]->span.flags & ZT_FLAG_REGISTERED)
+ zt_unregister(&wc->tspans[2]->span);
+ if (wc->tspans[3]->span.flags & ZT_FLAG_REGISTERED)
+ zt_unregister(&wc->tspans[3]->span);
+ }
#ifdef ENABLE_WORKQUEUES
if (wc->workq) {
flush_workqueue(wc->workq);
@@ -2768,7 +2806,7 @@ static void __devexit t4_remove_one(struct pci_dev *pdev)
#endif
cards[wc->num] = NULL;
pci_set_drvdata(pdev, NULL);
- for (x=0;x<4;x++) {
+ for (x=0;x<wc->numspans;x++) {
if (wc->tspans[x])
kfree(wc->tspans[x]);
}
@@ -2782,11 +2820,13 @@ static struct pci_device_id t4_pci_tbl[] __devinitdata =
{ 0x10ee, 0x0314, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&wct4xxp },
{ 0xd161, 0x0410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&wct410p2 },
{ 0xd161, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&wct405p2 },
+ { 0xd161, 0x0205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&wct205 },
+ { 0xd161, 0x0210, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&wct210 },
{ 0, }
};
static struct pci_driver t4_driver = {
- name: "t4xxp",
+ name: "Unified t4xxp/t2xxp driver",
probe: t4_init_one,
#ifdef LINUX26
remove: __devexit_p(t4_remove_one),
@@ -2814,7 +2854,7 @@ static void __exit t4_cleanup(void)
MODULE_AUTHOR("Mark Spencer");
-MODULE_DESCRIPTION("TE410P PCI Driver");
+MODULE_DESCRIPTION("Unified TE4XXP/TE2XXP PCI Driver");
#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
#endif