[Asterisk-cvs] zaptel wct4xxp.c,1.75,1.76

mattf at lists.digium.com mattf at lists.digium.com
Wed Jul 13 13:32:44 CDT 2005


Update of /usr/cvsroot/zaptel
In directory mongoose.digium.com:/tmp/cvs-serv28410

Modified Files:
	wct4xxp.c 
Log Message:
Add support for dual span cards


Index: wct4xxp.c
===================================================================
RCS file: /usr/cvsroot/zaptel/wct4xxp.c,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -d -r1.75 -r1.76
--- wct4xxp.c	22 Jun 2005 16:29:25 -0000	1.75
+++ wct4xxp.c	13 Jul 2005 17:40:46 -0000	1.76
@@ -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 @@
 #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 @@
 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 @@
 	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	
@@ -770,7 +774,7 @@
 			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 {
@@ -794,7 +798,7 @@
 			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;
 	   }
     }
@@ -865,7 +869,7 @@
 
 	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;
 	}
 
@@ -876,12 +880,17 @@
 	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 */
@@ -902,7 +911,7 @@
 
 	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;
@@ -913,7 +922,7 @@
 		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;
@@ -942,9 +951,9 @@
 	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)
@@ -984,11 +993,11 @@
 	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;
@@ -1022,7 +1031,7 @@
 		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;
@@ -1040,7 +1049,7 @@
 {
 	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 */
 	
@@ -1096,12 +1105,12 @@
 		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);
@@ -1111,11 +1120,11 @@
 			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);
@@ -1126,7 +1135,7 @@
 {
 	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) )) {
@@ -1228,7 +1237,7 @@
 		__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)
@@ -1314,7 +1323,7 @@
 		__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)
@@ -1331,7 +1340,7 @@
 	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;
 	}
 
@@ -1390,8 +1399,10 @@
 	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();
@@ -1417,7 +1428,9 @@
 		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);
@@ -1447,17 +1460,19 @@
 		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;
 		}
@@ -1465,17 +1480,21 @@
 			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)
@@ -1485,7 +1504,7 @@
 		/* 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 */
@@ -1566,7 +1585,7 @@
 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]);
@@ -1590,7 +1609,7 @@
 	} 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);
 	}
@@ -1609,10 +1628,12 @@
 			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)
@@ -1794,7 +1815,7 @@
 	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);
@@ -1803,7 +1824,7 @@
 	} 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);
@@ -1824,7 +1845,7 @@
 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) {
@@ -1842,7 +1863,7 @@
 	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)) {
@@ -2043,17 +2064,17 @@
 	}
 	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);
 	}
 }
 
@@ -2111,7 +2132,7 @@
 	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
@@ -2120,14 +2141,16 @@
 			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
@@ -2419,9 +2442,9 @@
 	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 */
@@ -2477,10 +2500,10 @@
 	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)) {
@@ -2492,18 +2515,21 @@
 		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);
@@ -2540,6 +2566,12 @@
 				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);
@@ -2552,9 +2584,9 @@
 				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;
 
@@ -2562,7 +2594,7 @@
 				/* 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;
 			}
 
@@ -2607,13 +2639,13 @@
 #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]) {
@@ -2644,7 +2676,7 @@
 
 
 #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, "wctxxp", wc)) 
 #else
 			if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN)) {
 				printk("This driver does not support 1st gen modules\n");
@@ -2711,7 +2743,7 @@
 	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;
 }
 
@@ -2728,10 +2760,12 @@
 			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);
@@ -2764,7 +2798,7 @@
 #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]);
 		}
@@ -2778,11 +2812,13 @@
 	{ 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),
@@ -2810,7 +2846,7 @@
 
 
 MODULE_AUTHOR("Mark Spencer");
-MODULE_DESCRIPTION("TE410P PCI Driver");
+MODULE_DESCRIPTION("Unified TE4XXP/TE2XXP PCI Driver");
 #ifdef MODULE_LICENSE
 MODULE_LICENSE("GPL");
 #endif




More information about the svn-commits mailing list