diff -rupN originales/dahdi-linux-2.1.0.4/drivers/dahdi/dahdi-base.c dahdi-linux-2.1.0.4/drivers/dahdi/dahdi-base.c
--- originales/dahdi-linux-2.1.0.4/drivers/dahdi/dahdi-base.c	2009-01-28 02:55:34.000000000 +0000
+++ dahdi-linux-2.1.0.4/drivers/dahdi/dahdi-base.c	2009-04-08 12:42:02.000000000 +0100
@@ -5940,11 +5940,40 @@ static inline void __dahdi_getbuf_chunk(
 					*(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc);
 				}
 				bytes -= left;
+#ifdef CONFIG_DAHDI_BRI_DCHANS
+			} else if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
+			    /*
+			     * Let's get this right, we want to transmit complete frames only.
+			     * The card driver will do the dirty HDLC work for us.
+			     * txb (transmit buffer) is supposed to be big enough to store one frame
+			     * we will make this as big as the D fifo (1KB or 2KB)
+			     */
+
+			    /* there are 'left' bytes in the user buffer left to transmit */
+			    left = ms->writen[ms->outwritebuf] - ms->writeidx[ms->outwritebuf] - 2;
+			    if (left > ms->maxbytes2transmit) {
+				memcpy(txb, buf + ms->writeidx[ms->outwritebuf], ms->maxbytes2transmit);
+				ms->writeidx[ms->outwritebuf] += ms->maxbytes2transmit;
+				txb += ms->maxbytes2transmit;
+				ms->bytes2transmit = ms->maxbytes2transmit;
+				ms->eoftx = 0;
+			    } else {
+				memcpy(txb, buf + ms->writeidx[ms->outwritebuf], left);
+				ms->writeidx[ms->outwritebuf] += left + 2;
+				txb += left + 2;
+				ms->bytes2transmit = left;
+				ms->eoftx = 1;
+			    }
+			    bytes = 0;
+#endif
 			} else {
 				memcpy(txb, buf + ms->writeidx[ms->outwritebuf], left);
 				ms->writeidx[ms->outwritebuf]+=left;
 				txb += left;
 				bytes -= left;
+#if defined(CONFIG_DAHDI_BRI_DCHANS)	
+				ms->bytes2transmit=DAHDI_CHUNKSIZE;
+#endif
 			}
 			/* Check buffer status */
 			if (ms->writeidx[ms->outwritebuf] >= ms->writen[ms->outwritebuf]) {
@@ -6001,6 +6030,17 @@ out in the later versions, and is put ba
 				/* Transmit a flag if this is an HDLC channel */
 				if (ms->flags & DAHDI_FLAG_HDLC)
 					fasthdlc_tx_frame_nocheck(&ms->txhdlc);
+#if defined(CONFIG_DAHDI_BRI_DCHANS)	
+				if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
+			//	    if (ms->bytes2transmit > 0) {
+					// txb += 2;
+					// ms->bytes2transmit -= 2;
+					bytes=0;
+					ms->eoftx = 1;
+//					printk(KERN_CRIT "zaptel EOF(%d) bytes2transmit %d\n",ms->eoftx,ms->bytes2transmit);
+			//	    }
+				}
+#endif
 #ifdef CONFIG_DAHDI_NET
 				if (ms->flags & DAHDI_FLAG_NETDEV)
 					netif_wake_queue(ztchan_to_dev(ms));
@@ -6061,6 +6101,12 @@ out in the later versions, and is put ba
 				memset(txb, 0xFF, bytes);
 			}
 			bytes = 0;
+#if defined(CONFIG_DAHDI_BRI_DCHANS)	
+		} else if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
+		    ms->bytes2transmit = 0;
+		    ms->eoftx = 0;
+		    bytes = 0;
+#endif
 		} else {
 			memset(txb, DAHDI_LIN2X(0, ms), bytes);	/* Lastly we use silence on telephony channels */
 			bytes = 0;
@@ -6873,6 +6919,14 @@ static inline void __putbuf_chunk(struct
 	int res;
 	int left, x;
 
+#if defined(CONFIG_DAHDI_BRI_DCHANS)	
+	if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
+	    bytes = ms->bytes2receive;
+	    if (bytes < 1) return;
+//	    printk(KERN_CRIT "bytes2receive %d\n",ms->bytes2receive);
+	}
+#endif
+
 	while(bytes) {
 #if defined(CONFIG_DAHDI_NET)  || defined(CONFIG_DAHDI_PPP)
 		skb = NULL;
@@ -6930,6 +6984,19 @@ static inline void __putbuf_chunk(struct
 						}
 					}
 				}
+#ifdef CONFIG_DAHDI_BRI_DCHANS
+			} else if (test_bit(DAHDI_FLAGBIT_BRIDCHAN, &ms->flags)) {
+			    memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left);
+			    rxb += left;
+			    ms->readidx[ms->inreadbuf] += left;
+			    bytes -= left;
+			    if (ms->eofrx == 1) {
+				eof=1;
+			    }
+//			    printk(KERN_CRIT "receiving %d bytes\n",ms->bytes2receive);
+			    ms->bytes2receive = 0;
+			    ms->eofrx = 0;
+#endif
 			} else {
 				/* Not HDLC */
 				memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left);
diff -rupN originales/dahdi-linux-2.1.0.4/drivers/dahdi/dahdi_config.h dahdi-linux-2.1.0.4/drivers/dahdi/dahdi_config.h
--- originales/dahdi-linux-2.1.0.4/drivers/dahdi/dahdi_config.h	2008-10-03 21:09:40.000000000 +0100
+++ dahdi-linux-2.1.0.4/drivers/dahdi/dahdi_config.h	2009-04-08 12:42:02.000000000 +0100
@@ -174,4 +174,10 @@
  */
 /* #define	OPTIMIZE_CHANMUTE */
 
+/*
+ * Uncomment the following for BRI D channels
+ *
+ */
+#define CONFIG_DAHDI_BRI_DCHANS
+
 #endif
diff -rupN originales/dahdi-linux-2.1.0.4/drivers/dahdi/Kbuild dahdi-linux-2.1.0.4/drivers/dahdi/Kbuild
--- originales/dahdi-linux-2.1.0.4/drivers/dahdi/Kbuild	2008-10-28 18:26:33.000000000 +0000
+++ dahdi-linux-2.1.0.4/drivers/dahdi/Kbuild	2009-04-08 04:38:42.000000000 +0100
@@ -11,7 +11,7 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE12XP)		+= wcte12xp/
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM)		+= wctdm.o
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCB4XXP)		+= wcb4xxp/
-
+obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_HFCS)		+= zaphfc.o 
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT1XXP)		+= wct1xxp.o
 obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE11XP)		+= wcte11xp.o
 
diff -rupN originales/dahdi-linux-2.1.0.4/drivers/dahdi/wcb4xxp/base.c dahdi-linux-2.1.0.4/drivers/dahdi/wcb4xxp/base.c
--- originales/dahdi-linux-2.1.0.4/drivers/dahdi/wcb4xxp/base.c	2008-12-17 15:57:56.000000000 +0000
+++ dahdi-linux-2.1.0.4/drivers/dahdi/wcb4xxp/base.c	2009-04-08 13:49:47.000000000 +0100
@@ -47,6 +47,15 @@
 
 #include "wcb4xxp.h"
 
+#ifndef BIT     /* added in 2.6.24 */
+#define BIT(i)          (1UL << (i))
+#endif
+#define BIT_SET(x, i)    ((x) |= BIT(i))
+#define BIT_CLR(x, i)    ((x) &= ~BIT(i))
+#define IS_SET(x, i)     (((x) & BIT(i)) != 0)
+#define BITMASK(i)      (((u64)1 << (i)) - 1)
+
+
 #if (DAHDI_CHUNKSIZE != 8)
 #error Sorry, wcb4xxp does not support chunksize != 8
 #endif
@@ -72,10 +81,10 @@
 #define DBG_HDLC		(debug & DEBUG_HDLC)
 #define DBG_ALARM		(debug & DEBUG_ALARM)
 
-#define DBG_SPANFILTER		((1 << bspan->port) & spanfilter)
+#define DBG_SPANFILTER		(BIT(bspan->port) & spanfilter)
 
 static int debug = 0;
-static int spanfilter = 15;
+static int spanfilter = 0xFF; /* Bitmap for ports 1-8 */
 #ifdef LOOPBACK_SUPPORTED
 static int loopback = 0;
 #endif
@@ -110,10 +119,23 @@ static struct proc_dir_entry *myproc;
 struct devtype {
 	char *desc;
 	unsigned int flags;
+	int ports;   	/* Number of ports the card has */
+	enum cards_ids card_type;	/* Card type - Digium B410P, ... */
 };
 
-static struct devtype wcb4xxp = { "Wildcard B410P", 0 };
+static struct devtype wcb4xxp =  {"Wildcard B410P", .ports = 4, .card_type = B410P  };
+static struct devtype hfc2s =	 {"HFC-2S Junghanns.NET duoBRI PCI", .ports = 2, .card_type = DUOBRI };
+static struct devtype hfc4s =	 {"HFC-4S Junghanns.NET quadBRI PCI", .ports = 4, .card_type = QUADBRI };
+static struct devtype hfc8s =	 {"HFC-4S Junghanns.NET octoBRI PCI", .ports = 8, .card_type = OCTOBRI };
+static struct devtype hfc2s_OV = {"OpenVox B200P", .ports = 2, .card_type = B200P_OV };
+static struct devtype hfc4s_OV = {"OpenVox B400P", .ports = 4, .card_type = B400P_OV };
+static struct devtype hfc8s_OV = {"OpenVox B800P", .ports = 8, .card_type = B800P_OV };
+static struct devtype hfc2s_BN = {"BeroNet BN2S0", .ports = 2, .card_type = BN2S0 };
+static struct devtype hfc4s_BN = {"BeroNet BN4S0", .ports = 4, .card_type = BN4S0 };
+static struct devtype hfc8s_BN = {"BeroNet BN8S0", .ports = 8, .card_type = BN8S0 };
+static struct devtype hfc4s_EV = {"CCD HFC-4S Eval. Board", .ports = 4, .card_type = QUADBRI_EVAL };
 
+#define CARD_HAS_EC(card) ((card)->card_type == B410P)
 
 #if 0
 static const char *wcb4xxp_rcsdata = "$RCSfile: base.c,v $ $Revision: 5576 $";
@@ -385,7 +407,18 @@ static void hfc_gpio_init(struct b4xxp *
 
 	mb();
 
-	b4xxp_setreg8(b4, R_GPIO_SEL, 0xf0);	/* GPIO0..7 S/T, 8..15 GPIO */
+	switch (b4->card_type) {
+	case OCTOBRI:  /* fall through */
+	case B800P_OV: /* fall through */
+	case BN8S0:
+		/* GPIO0..15 S/T - HFC-8S uses GPIO8-15 for S/T ports 5-8 */
+		b4xxp_setreg8(b4, R_GPIO_SEL, 0x00);
+		break;
+	default:
+		/* GPIO0..7 S/T, 8..15 GPIO */
+		b4xxp_setreg8(b4, R_GPIO_SEL, 0xf0);
+		break;
+	}
 
 	mb();
 
@@ -600,13 +633,16 @@ static void ec_init(struct b4xxp *b4)
 	unsigned char b;
 	unsigned int i, j, mask;
 
+	if (!CARD_HAS_EC(b4))
+		return;
+
 /* Setup GPIO */
 	for (i=0; i < NUM_EC; i++) {
 		b = ec_read(b4, i, 0x1a0);
 
 		dev_info(b4->dev, "VPM %d/%d init: chip ver %02x\n", i, NUM_EC - 1, b);
 
-		for (j=0; j < 4; j++) {
+		for (j=0; j < b4->numspans; j++) {
 			ec_write(b4, i, 0x1a8 + j, 0x00);	/* GPIO out */
 			ec_write(b4, i, 0x1ac + j, 0x00);	/* GPIO dir */
 			ec_write(b4, i, 0x1b0 + j, 0x00);	/* GPIO sel */
@@ -990,7 +1026,18 @@ static void hfc_assign_dchan_fifo(struct
 	int fifo, hfc_chan;
 	unsigned long irq_flags;
 
-	fifo = port + 8;
+	switch (b4->card_type) {
+	case B800P_OV: /* fall through */
+	case OCTOBRI: /* fall through */
+	case BN8S0:
+		/* In HFC-8S cards we can't use ports 8-11 for dchan FIFOs */
+		fifo = port + 16;
+		break;
+	default:
+		fifo = port + 8;
+		break;
+	}
+
 	hfc_chan = (port * 4) + 2;
 
 /* record the host's FIFO # in the span fifo array */
@@ -1192,7 +1239,7 @@ static void hfc_update_st_timers(struct 
 	int i, j;
 	struct b4xxp_span *s;
 
-	for (i=0; i < 4; i++) {
+	for (i=0; i < b4->numspans; i++) {
 		s = &b4->spans[i];
 
 		for (j=HFC_T1; j <= HFC_T3; j++) {
@@ -1394,12 +1441,21 @@ static void hfc_init_all_st(struct b4xxp
 
 	gpio = b4xxp_getreg8(b4, R_GPI_IN3);
 
-	for (i=0; i < 4; i++) {
+	for (i=0; i < b4->numspans; i++) {
 		s = &b4->spans[i];
 		s->parent = b4;
 		s->port = i;
 
-		nt = ((gpio & (1 << (i + 4))) == 0);		/* GPIO=0 = NT mode */
+		/* The way the Digium B410P card reads the NT/TE mode
+		 * jumper is the oposite of how other HFC-4S cards do:
+		 * - In B410P: GPIO=0: NT
+		 * - In Junghanns: GPIO=0: TE
+		 */
+		if (b4->card_type == B410P)
+			nt = ((gpio & (1 << (i + 4))) == 0);
+		else
+			nt = ((gpio & (1 << (i + 4))) != 0);
+
 		s->te_mode = !nt;
 
 		dev_info(b4->dev, "Port %d: %s mode\n", i + 1, (nt ? "NT" : "TE"));
@@ -1755,9 +1811,15 @@ static void b4xxp_init_stage1(struct b4x
 
 /*
  * set up the clock controller
- * we have a 24.576MHz crystal, so the PCM clock is 2x the incoming clock.
+ * B410P & Cologne Eval Board have a 24.576MHz crystal, so the PCM clock is 2x the incoming clock.
+ * Other cards have a 49.152Mhz crystal, so the PCM clock equals incoming clock.
  */
-	b4xxp_setreg8(b4, R_BRG_PCM_CFG, 0x02);
+
+	if ((b4->card_type == B410P) || (b4->card_type == QUADBRI_EVAL))
+		b4xxp_setreg8(b4, R_BRG_PCM_CFG, 0x02);
+	else
+		b4xxp_setreg8(b4, R_BRG_PCM_CFG, V_PCM_CLK);
+
 	flush_pci();
 
 	udelay(100);				/* wait a bit for clock to settle */
@@ -1788,7 +1850,7 @@ static void b4xxp_init_stage2(struct b4x
 
 /*
  * set up the flow controller.
- * B channel map:
+ * B channel map: (4 ports cards with Hardware Echo Cancel present & active)
  * FIFO 0 connects Port 1 B0 using HFC channel 16 and PCM timeslots 0/1.
  * FIFO 1 connects Port 1 B1 using HFC channel 17 and PCM timeslots 4/5.
  * FIFO 2 connects Port 2 B0 using HFC channel 20 and PCM timeslots 8/9.
@@ -1803,14 +1865,35 @@ static void b4xxp_init_stage2(struct b4x
  *
  * D channels are handled by FIFOs 8-11.
  * FIFO 8 connects Port 1 D using HFC channel 3
- * FIFO 9 connects Port 1 D using HFC channel 7
- * FIFO 10 connects Port 1 D using HFC channel 11
- * FIFO 11 connects Port 1 D using HFC channel 15
+ * FIFO 9 connects Port 2 D using HFC channel 7
+ * FIFO 10 connects Port 3 D using HFC channel 11
+ * FIFO 11 connects Port 4 D using HFC channel 15
+ *
+ * D channel FIFOs are operated in HDLC mode and interrupt on end of frame.
  *
+ * B channel map: (8 ports cards without Hardware Echo Cancel)
+ * FIFO 0 connects Port 1 B0 using HFC channel 0
+ * FIFO 1 connects Port 1 B1 using HFC channel 1
+ * FIFO 2 connects Port 2 B0 using HFC channel 4
+ * FIFO 3 connects Port 2 B1 using HFC channel 5
+ * .........................
+ * FIFO 14 connects Port 8 B0 using HFC channel 28
+ * FIFO 15 connects Port 8 B1 using HFC channel 29
+ *
+ * All B channel FIFOs have their HDLC controller in transparent mode,
+ * and only the FIFO for B0 on each port has its interrupt operational.
+ *
+ * D channels are handled by FIFOs 16-23.
+ * FIFO 16 connects Port 1 D using HFC channel 3
+ * FIFO 17 connects Port 2 D using HFC channel 7
+ * FIFO 18 connects Port 3 D using HFC channel 11
+ * FIFO 19 connects Port 4 D using HFC channel 15
+ * ................
+ * FIFO 23 connects Port 8 D using HFC channel 31
  * D channel FIFOs are operated in HDLC mode and interrupt on end of frame.
  */
 	for (span=0; span < b4->numspans; span++) {
-		if (vpmsupport) {
+		if ((vpmsupport) && (CARD_HAS_EC(b4))) {
 			hfc_assign_bchan_fifo_ec(b4, span, 0);
 			hfc_assign_bchan_fifo_ec(b4, span, 1);
 		} else {
@@ -1835,6 +1918,79 @@ static void b4xxp_setleds(struct b4xxp *
 	ec_write(b4, 0, 0x1a8 + 3, val);
 }
 
+static void b4xxp_update_leds_hfc_8s(struct b4xxp *b4)
+{
+	unsigned long lled = 0; /* A bit set is a led OFF */
+	unsigned long leddw;
+	int j;
+	struct b4xxp_span *bspan;
+
+	b4->blinktimer++;
+	for (j = 7; j >= 0; j--) {
+		bspan = &b4->spans[7 - j];
+		if (!(bspan->span.flags & DAHDI_FLAG_RUNNING) ||
+				bspan->span.alarms) {
+			BIT_SET(lled, j);
+			continue;  /* Led OFF */
+		}
+
+		if (bspan->span.mainttimer || bspan->span.maintstat) {
+			/* Led Blinking in maint state */
+			if (b4->blinktimer >= 0x7f)
+				BIT_SET(lled, j);
+		}
+		/* Else: Led on */
+	}
+
+	/* Write Leds...*/
+	leddw = lled << 24 | lled << 16 | lled << 8 | lled;
+	b4xxp_setreg8(b4, R_BRG_PCM_CFG, 0x21);
+	iowrite16(0x4000, b4->ioaddr + 4);
+	iowrite32(leddw, b4->ioaddr);
+	b4xxp_setreg8(b4, R_BRG_PCM_CFG, 0x20);
+
+	if (b4->blinktimer == 0xff)
+		b4->blinktimer = -1;
+}
+
+/* So far only tested for OpenVox cards. Please test it for other hardware */
+static void b4xxp_update_leds_hfc(struct b4xxp *b4)
+{
+	int i;
+	int leds = 0, green_leds = 0; /* Default: off */
+	struct b4xxp_span *bspan;
+
+	b4->blinktimer++;
+	for (i=0; i < b4->numspans; i++) {
+		bspan = &b4->spans[i];
+
+		if (!(bspan->span.flags & DAHDI_FLAG_RUNNING))
+			continue; /* Leds are off */
+
+		if (bspan->span.alarms) {
+			/* Red blinking -> Alarm */
+			if (b4->blinktimer >= 0x7f)
+				BIT_SET(leds, i);
+		} else if (bspan->span.mainttimer || bspan->span.maintstat) {
+			/* Green blinking -> Maint status */
+			if (b4->blinktimer >= 0x7f)
+				BIT_SET(green_leds, i);
+		} else {
+			/* Steady grean -> No Alarm */
+			BIT_SET(green_leds, i);
+		}
+	}
+
+	/* Actually set them. for red: just set the bit in R_GPIO_EN1.
+	   For green: in both R_GPIO_EN1 and R_GPIO_OUT1. */
+	leds |= green_leds;
+	b4xxp_setreg8(b4, R_GPIO_EN1, leds);
+	b4xxp_setreg8(b4, R_GPIO_OUT1, green_leds);
+
+	if (b4->blinktimer == 0xff)
+		b4->blinktimer = -1;
+}
+
 static void b4xxp_set_span_led(struct b4xxp *b4, int span, unsigned char val)
 {
 	int shift, spanmask;
@@ -1852,6 +2008,18 @@ static void b4xxp_update_leds(struct b4x
 	int i;
 	struct b4xxp_span *bspan;
 
+	if (b4->numspans == 8) {
+		/* Use the alternative function for non-Digium HFC-8S cards */
+		b4xxp_update_leds_hfc_8s(b4);
+		return;
+	}
+
+	if (b4->card_type != B410P) {
+		/* Use the alternative function for non-Digium HFC-4S cards */
+		b4xxp_update_leds_hfc(b4);
+		return;
+	}
+
 	b4->blinktimer++;
 	for (i=0; i < b4->numspans; i++) {
 		bspan = &b4->spans[i];
@@ -2138,7 +2306,7 @@ static void init_spans(struct b4xxp *b4)
 		bspan->span.close  = b4xxp_close;
 		bspan->span.ioctl = b4xxp_ioctl;
 		bspan->span.hdlc_hard_xmit = b4xxp_hdlc_hard_xmit;
-		if (vpmsupport)
+		if (vpmsupport && CARD_HAS_EC(b4))
 			bspan->span.echocan = b4xxp_echocan;
 
 /* HDLC stuff */
@@ -2245,13 +2413,21 @@ DAHDI_IRQ_HANDLER(b4xxp_interrupt)
 static void b4xxp_bottom_half(unsigned long data)
 {
 	struct b4xxp *b4 = (struct b4xxp *)data;
-	int i, j, k, gotrxfifo, fifo;
+	int i, j, k, gotrxfifo, fifo, fifo_low, fifo_high;
 	unsigned char b, b2;
 
 	if (b4->shutdown)
 		return;
 
 	gotrxfifo = 0;
+	/* HFC-4S d-chan fifos 8-11 *** HFC-8S d-chan fifos 16-23 */
+	if (b4->numspans == 8) {
+		fifo_low = 16;
+		fifo_high = 23;
+	} else {
+		fifo_low = 8;
+		fifo_high = 11;
+	}
 
 	for (i=0; i < 8; i++) {
 		b = b2 = b4->fifo_irqstatus[i];
@@ -2260,7 +2436,8 @@ static void b4xxp_bottom_half(unsigned l
 			fifo = i*4 + j;
 
 			if (b & V_IRQ_FIFOx_TX) {
-				if (fifo >=8 && fifo <= 11) {		/* d-chan fifo */
+				if (fifo >= fifo_low && fifo <= fifo_high) {
+					/* d-chan fifos */
 /*
  * WOW I don't like this.
  * It's bad enough that I have to send a fake frame to get an HDLC TX FIFO interrupt,
@@ -2269,7 +2446,7 @@ static void b4xxp_bottom_half(unsigned l
  * Yuck.  It works well, but yuck.
  */
 					do {
-						k = hdlc_tx_frame(&b4->spans[fifo - 8]);
+						k = hdlc_tx_frame(&b4->spans[fifo - fifo_low]);
 					}  while (k);
 				} else {
 					if (printk_ratelimit())
@@ -2278,7 +2455,7 @@ static void b4xxp_bottom_half(unsigned l
 			}
 
 			if (b & V_IRQ_FIFOx_RX) {
-				if (fifo >=8 && fifo <= 11) {
+				if (fifo >= fifo_low && fifo <= fifo_high) {	/* dchan fifos */
 /*
  * I have to loop here until hdlc_rx_frame says there are no more frames waiting.
  * for whatever reason, the HFC will not generate another interrupt if there are
@@ -2286,7 +2463,7 @@ static void b4xxp_bottom_half(unsigned l
  * i.e. I get an int when F1 changes, not when F1 != F2.
  */
 					do {
-						k = hdlc_rx_frame(&b4->spans[fifo - 8]);
+						k = hdlc_rx_frame(&b4->spans[fifo - fifo_low]);
 					} while (k);
 				} else {
 					if (printk_ratelimit())
@@ -2368,8 +2545,8 @@ static int b4xxp_proc_read_one(char *buf
 	sprintf(sBuf, "Card %d, PCI identifier %s, IRQ %d\n", b4->cardno + 1, b4->dev->bus_id, b4->irq);
 
 	strcat(sBuf,"Tx:\n");
-	for (j=0; j<8; j++) {
-		for (i=0; i<12; i++) {
+	for (j=0; j<(b4->numspans * 2) ; j++) {			/* B Channels */
+		for (i=0; i<(b4->numspans * 3) ; i++) {		/* All Channels */
 			chan = b4->spans[i/3].chans[i%3];
 			sprintf(str, "%02x ", chan->writechunk[j]);
 			strcat(sBuf, str);
@@ -2379,8 +2556,8 @@ static int b4xxp_proc_read_one(char *buf
 	}
 
 	strcat(sBuf, "\nRx:\n");
-	for (j=0; j < 8; j++) {
-		for (i=0; i < 12; i++) {
+	for (j=0; j < (b4->numspans * 2); j++) {		/* B Channels */
+		for (i=0; i < (b4->numspans * 3); i++) { 	/* All Channels */
 			chan = b4->spans[i / 3].chans[i % 3];
 			sprintf(str, "%02x%c", chan->readchunk[j], (i == 11) ? '\n' : ' ');
 			strcat(sBuf, str);
@@ -2388,7 +2565,7 @@ static int b4xxp_proc_read_one(char *buf
 	}
 
 	strcat(sBuf, "\nPort states:\n");
-	for (i=0; i < 4; i++) {
+	for (i=0; i < b4->numspans; i++) {
 		int state;
 		char *x;
 		struct b4xxp_span *s = &b4->spans[i];
@@ -2483,7 +2660,7 @@ static int __devinit b4xx_probe(struct p
 /* card found, enabled and main struct allocated.  Fill it out. */
 	b4->magic = WCB4XXP_MAGIC;
 	b4->variety = dt->desc;
-
+	b4->card_type = dt->card_type;
 	b4->pdev = pdev;
 	b4->dev = &pdev->dev;
 	pci_set_drvdata(pdev, b4);
@@ -2497,7 +2674,7 @@ static int __devinit b4xx_probe(struct p
 	spin_lock_init(&b4->fifolock);
 
 	x = b4xxp_getreg8(b4, R_CHIP_ID);
-	if (x != 0xc0) {				/* wrong chip? */
+	if ((x != 0xc0) && (x != 0x80)) {		/* wrong chip? */
 		dev_err(&pdev->dev, "Unknown/unsupported controller detected (R_CHIP_ID = 0x%02x)\n", x);
 		goto err_out_free_mem;
 	}
@@ -2512,7 +2689,7 @@ static int __devinit b4xx_probe(struct p
 */
 
 /* TODO: determine whether this is a 2, 4 or 8 port card */
-	b4->numspans = 4;
+	b4->numspans = dt->ports;
 	b4->syncspan = -1;		/* sync span is unknown */
 	if (b4->numspans > MAX_SPANS_PER_CARD) {
 		dev_err(b4->dev, "Driver does not know how to handle a %d span card!\n", b4->numspans);
@@ -2660,7 +2837,18 @@ static void __devexit b4xxp_remove(struc
 static struct pci_device_id b4xx_ids[] __devinitdata =
 {
 	{ 0xd161, 0xb410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long)&wcb4xxp },
-	{ 0, }
+	{ 0x1397, 0x16b8, 0x1397, 0xe552, 0, 0, (unsigned long)&hfc8s },
+	{ 0x1397, 0x08b4, 0x1397, 0xb520, 0, 0, (unsigned long)&hfc4s },
+	{ 0x1397, 0x08b4, 0x1397, 0xb556, 0, 0, (unsigned long)&hfc2s },
+	{ 0x1397, 0x08b4, 0x1397, 0xe884, 0, 0, (unsigned long)&hfc2s_OV },
+	{ 0x1397, 0x08b4, 0x1397, 0xe888, 0, 0, (unsigned long)&hfc4s_OV },
+	{ 0x1397, 0x16b8, 0x1397, 0xe998, 0, 0, (unsigned long)&hfc8s_OV },
+	{ 0x1397, 0x08b4, 0x1397, 0xb566, 0, 0, (unsigned long)&hfc2s_BN },
+	{ 0x1397, 0x08b4, 0x1397, 0xb560, 0, 0, (unsigned long)&hfc4s_BN },
+	{ 0x1397, 0x16b8, 0x1397, 0xb562, 0, 0, (unsigned long)&hfc8s_BN },
+	{ 0x1397, 0x08b4, 0x1397, 0x08b4, 0, 0, (unsigned long)&hfc4s_EV },
+	{0, }
+
 };
 
 static struct pci_driver b4xx_driver = {
@@ -2719,7 +2907,7 @@ MODULE_PARM_DESC(timer_1_ms, "NT: msec t
 MODULE_PARM_DESC(timer_3_ms, "TE: msec to wait for link activation, NT: unused.");
 
 MODULE_AUTHOR("Digium Incorporated <support@digium.com>");
-MODULE_DESCRIPTION("B410P quad-port BRI module driver.");
+MODULE_DESCRIPTION("B410P & Similars multi-port BRI module driver.");
 MODULE_LICENSE("GPL");
 
 MODULE_DEVICE_TABLE(pci, b4xx_ids);
diff -rupN originales/dahdi-linux-2.1.0.4/drivers/dahdi/wcb4xxp/wcb4xxp.h dahdi-linux-2.1.0.4/drivers/dahdi/wcb4xxp/wcb4xxp.h
--- originales/dahdi-linux-2.1.0.4/drivers/dahdi/wcb4xxp/wcb4xxp.h	2008-11-24 04:14:37.000000000 +0000
+++ dahdi-linux-2.1.0.4/drivers/dahdi/wcb4xxp/wcb4xxp.h	2009-04-08 12:20:36.000000000 +0100
@@ -378,7 +378,7 @@
 #define HFC_T3					2
 
 #define WCB4XXP_MAGIC				0xb410c0de
-#define MAX_SPANS_PER_CARD			4
+#define MAX_SPANS_PER_CARD			8
 
 #define WCB4XXP_CHANNELS_PER_SPAN		3	/* 2 B-channels and 1 D-Channel for each BRI span */
 #define WCB4XXP_HDLC_BUF_LEN			32	/* arbitrary, just the max # of byts we will send to DAHDI per call */
@@ -414,6 +414,20 @@ struct b4xxp_span {
 	struct dahdi_chan _chans[WCB4XXP_CHANNELS_PER_SPAN]; /* Backing memory */
 };
 
+enum cards_ids {	/* Cards ==> Brand & Model 		*/
+	B410P = 0,	/* Digium B410P 			*/
+	B200P_OV,	/* OpenVox B200P 			*/
+	B400P_OV,	/* OpenVox B400P 			*/
+	B800P_OV,	/* OpenVox B800P 			*/
+	DUOBRI,		/* HFC-2S Junghanns.NET duoBRI PCI 	*/
+	QUADBRI,	/* HFC-4S Junghanns.NET quadBRI PCI	*/
+	OCTOBRI,	/* HFC-8S Junghanns.NET octoBRI PCI	*/
+	BN2S0,		/* BeroNet BN2S0			*/
+	BN4S0,		/* Beronet BN4S0			*/
+	BN8S0,		/* BeroNet BN8S0			*/
+	QUADBRI_EVAL	/* HFC-4S CCD Eval. Board		*/
+	};
+
 /* This structure exists one per card */
 struct b4xxp {
 	unsigned magic;				/* magic value to make sure we're looking at our struct */
@@ -452,6 +466,7 @@ struct b4xxp {
 	struct b4xxp_span spans[MAX_SPANS_PER_CARD];	/* Individual spans */
 	int order;				/* Order */
 	int flags;				/* Device flags */
+	enum cards_ids card_type;		/* For LED handling mostly */
 	int master;				/* Are we master */
 	int ledreg;				/* copy of the LED Register */
 	unsigned int gpio;
diff -rupN originales/dahdi-linux-2.1.0.4/drivers/dahdi/zaphfc.c dahdi-linux-2.1.0.4/drivers/dahdi/zaphfc.c
--- originales/dahdi-linux-2.1.0.4/drivers/dahdi/zaphfc.c	1970-01-01 00:00:00.000000000 +0000
+++ dahdi-linux-2.1.0.4/drivers/dahdi/zaphfc.c	2009-04-08 05:59:44.000000000 +0100
@@ -0,0 +1,915 @@
+/*
+ * zaphfc.c - Zaptel driver for HFC-S PCI A based ISDN BRI cards
+ *
+ * kernel module inspired by HFC PCI ISDN4Linux and Zaptel drivers
+ *
+ * Copyright (C) 2002, 2003, 2004, 2005 Junghanns.NET GmbH
+ *
+ * Klaus-Peter Junghanns <kpj@junghanns.net>
+ *
+ * Copyright (C) 2004, 2005, 2006  Florian Zumbiehl <florz@gmx.de>
+ *  - support for slave mode of the HFC-S chip which allows it to
+ *    sync its sample clock to an external source/another HFC chip
+ *  - support for "interrupt bundling" (let only one card generate
+ *    8 kHz timing interrupt no matter how many cards there are
+ *    in the system)
+ *  - interrupt loss tolerant b channel handling
+ *
+ * This program is free software and may be modified and
+ * distributed under the terms of the GNU General Public License.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <dahdi/kernel.h>
+#include "zaphfc.h"
+
+#include <linux/moduleparam.h>
+
+#define log2(n) ffz(~(n))
+
+#if CONFIG_PCI
+
+#define CLKDEL_TE	0x0f	/* CLKDEL in TE mode */
+#define CLKDEL_NT	0x6c	/* CLKDEL in NT mode */
+
+typedef struct {
+        int vendor_id;
+        int device_id;
+        char *vendor_name;
+        char *card_name;
+} PCI_ENTRY;
+
+static const PCI_ENTRY id_list[] =
+{
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0, "CCD/Billion/Asuscom", "2BD0"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000, "Billion", "B000"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006, "Billion", "B006"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007, "Billion", "B007"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008, "Billion", "B008"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009, "Billion", "B009"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A, "Billion", "B00A"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, "Billion", "B00B"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, "Billion", "B00C"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, "Seyeon", "B100"},
+        {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, "Abocom/Magitek", "2BD1"},
+        {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, "Asuscom/Askey", "675"},
+        {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, "German telekom", "T-Concept"},
+        {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T, "German telekom", "A1T"},
+        {PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575, "Motorola MC145575", "MC145575"},
+        {PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0, "Zoltrix", "2BD0"},
+        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E,"Digi International", "Digi DataFire Micro V IOM2 (Europe)"},
+        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,"Digi International", "Digi DataFire Micro V (Europe)"},
+        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,"Digi International", "Digi DataFire Micro V IOM2 (North America)"},
+        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,"Digi International", "Digi DataFire Micro V (North America)"},
+	{0x182d, 0x3069,"Sitecom","Isdn 128 PCI"},
+        {0, 0, NULL, NULL},
+};
+
+static struct hfc_card *hfc_dev_list = NULL;
+static int hfc_dev_count = 0;
+static int modes = 0; // all TE
+static int sync_slave = 0; // all master
+static int timer_card = 0;
+static int jitterbuffer = 1;
+static int debug = 0;
+static struct pci_dev *multi_hfc = NULL;
+static spinlock_t registerlock = SPIN_LOCK_UNLOCKED;
+
+void hfc_shutdownCard1(struct hfc_card *hfctmp) {
+    printk(KERN_INFO "zaphfc: shutting down card at %p.\n",hfctmp->pci_io);
+
+    /* Clear interrupt mask */
+    hfctmp->regs.int_m2 = 0;
+    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
+
+    /* Remove interrupt handler */
+    free_irq(hfctmp->irq,hfctmp);
+}
+
+void hfc_shutdownCard2(struct hfc_card *hfctmp) {
+    unsigned long flags;
+
+    spin_lock_irqsave(&hfctmp->lock,flags);
+
+    /* Reset pending interrupts */
+    hfc_inb(hfctmp, hfc_INT_S1);
+
+    /* Soft-reset the card */
+    hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET); // softreset on
+
+    spin_unlock_irqrestore(&hfctmp->lock, flags);
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
+    spin_lock_irqsave(&hfctmp->lock,flags);
+
+    hfc_outb(hfctmp,hfc_CIRM,0);	// softreset off
+
+    pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, 0);	// disable memio and bustmaster
+
+    if (hfctmp->fifos != NULL) {
+	free_pages((unsigned long)hfctmp->fifos,log2(hfc_FIFO_MEM_SIZE_PAGES));
+    }
+    iounmap((void *) hfctmp->pci_io);
+    hfctmp->pci_io = NULL;
+    if (hfctmp->pcidev != NULL) {
+        pci_disable_device(hfctmp->pcidev);
+    }
+    spin_unlock_irqrestore(&hfctmp->lock,flags);
+    if (hfctmp->ztdev != NULL) {
+	dahdi_unregister(&hfctmp->ztdev->span);
+	vfree(hfctmp->ztdev);
+	printk(KERN_INFO "unregistered from DAHDI.\n");
+    }
+}
+
+void hfc_shutdownCard(struct hfc_card *hfctmp) {
+    if (hfctmp == NULL) {
+	return;
+    }
+
+    if (hfctmp->pci_io == NULL) {
+	return;
+    }
+
+    hfc_shutdownCard1(hfctmp);
+    hfc_shutdownCard2(hfctmp);
+}
+
+void hfc_resetCard(struct hfc_card *hfctmp) {
+    unsigned long flags;
+
+    spin_lock_irqsave(&hfctmp->lock,flags);
+    pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY);	// enable memio
+    hfctmp->regs.int_m2 = 0;
+    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
+
+//    printk(KERN_INFO "zaphfc: resetting card.\n");
+    pci_set_master(hfctmp->pcidev);
+    hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET);	// softreset on
+    spin_unlock_irqrestore(&hfctmp->lock, flags);
+
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
+    hfc_outb(hfctmp, hfc_CIRM, 0);	// softreset off
+
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout((20 * HZ) / 1000);	// wait 20 ms
+    if (hfc_inb(hfctmp,hfc_STATUS) & hfc_STATUS_PCI_PROC) {
+	printk(KERN_WARNING "zaphfc: hfc busy.\n");
+    }
+
+//    hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
+//    hfctmp->regs.fifo_en = hfc_FIFOEN_D;	/* only D fifos enabled */
+    hfctmp->regs.fifo_en = 0;	/* no fifos enabled */
+    hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
+
+    hfctmp->regs.trm = 2;
+    hfc_outb(hfctmp, hfc_TRM, hfctmp->regs.trm);
+
+    if (hfctmp->regs.nt_mode == 1) {
+	hfc_outb(hfctmp, hfc_CLKDEL, CLKDEL_NT); /* ST-Bit delay for NT-Mode */
+    } else {
+	hfc_outb(hfctmp, hfc_CLKDEL, CLKDEL_TE); /* ST-Bit delay for TE-Mode */
+    }
+    hfctmp->regs.sctrl_e = hfc_SCTRL_E_AUTO_AWAKE;
+    hfc_outb(hfctmp, hfc_SCTRL_E, hfctmp->regs.sctrl_e);	/* S/T Auto awake */
+    hfctmp->regs.bswapped = 0;	/* no exchange */
+
+    hfctmp->regs.ctmt = hfc_CTMT_TRANSB1 | hfc_CTMT_TRANSB2; // all bchans are transparent , no freaking hdlc
+    hfc_outb(hfctmp, hfc_CTMT, hfctmp->regs.ctmt);
+
+    hfctmp->regs.int_m1=hfc_INTS_L1STATE;
+    if(hfctmp->cardno==timer_card){
+	hfctmp->regs.int_m2=hfc_M2_PROC_TRANS;
+    }else{
+	hfctmp->regs.int_m1|=hfc_INTS_DREC;
+	hfctmp->regs.int_m2=0;
+    }
+    hfc_outb(hfctmp, hfc_INT_M1, hfctmp->regs.int_m1);
+    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
+
+    /* Clear already pending ints */
+    hfc_inb(hfctmp, hfc_INT_S1);
+
+    if (hfctmp->regs.nt_mode == 1) {
+	hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_NT;	/* set tx_lo mode, error in datasheet ! */
+    } else {
+	hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_TE;	/* set tx_lo mode, error in datasheet ! */
+    }
+
+    hfc_outb(hfctmp, hfc_MST_MODE, hfctmp->regs.mst_mode);
+    hfc_outb(hfctmp, hfc_MST_EMOD, hfctmp->regs.mst_emod);
+
+    hfc_outb(hfctmp, hfc_SCTRL, hfctmp->regs.sctrl);
+    hfctmp->regs.sctrl_r = 3;
+    hfc_outb(hfctmp, hfc_SCTRL_R, hfctmp->regs.sctrl_r);
+
+    hfctmp->regs.connect = 0;
+    hfc_outb(hfctmp, hfc_CONNECT, hfctmp->regs.connect);
+
+    hfc_outb(hfctmp, hfc_CIRM, 0x80 | 0x40);	// bit order
+
+    /* Finally enable IRQ output */
+    hfctmp->regs.int_m2 |= hfc_M2_IRQ_ENABLE;
+    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
+
+    /* clear pending ints */
+    hfc_inb(hfctmp, hfc_INT_S1); 
+    hfc_inb(hfctmp, hfc_INT_S2);
+}
+
+void hfc_registerCard(struct hfc_card *hfccard) {
+    spin_lock(&registerlock);
+    if (hfccard != NULL) {
+	hfccard->cardno = hfc_dev_count++;
+	hfccard->next = hfc_dev_list;
+	hfc_dev_list = hfccard;
+    }
+    spin_unlock(&registerlock);
+}
+
+/*===========================================================================*/
+
+#if hfc_B_FIFO_SIZE%DAHDI_CHUNKSIZE
+#error hfc_B_FIFO_SIZE is not a multiple of DAHDI_CHUNKSIZE even though the code assumes this
+#endif
+
+static void hfc_dch_init(struct hfc_card *hfctmp){
+    struct dch *chtmp=&hfctmp->dch;
+
+    chtmp->rx.f1.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DRX_F1);
+    chtmp->rx.f2.v=0x1f;
+    chtmp->rx.f2.z2.v=0x1ff;
+
+    chtmp->tx.f1.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DTX_F1);
+    chtmp->tx.f1.v=0x1f;
+    chtmp->tx.f1.z1.v=0x1ff;
+    chtmp->tx.f2.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DTX_F2);
+}
+
+static void hfc_bch_init(struct hfc_card *hfctmp){
+    struct bch *chtmp=&hfctmp->bch;
+
+    chtmp->checkcnt=0;
+    chtmp->fill_fifo=0;
+
+    chtmp->rx.c[0].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1RX_Z1+0x1f*4);
+    chtmp->rx.c[0].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B1RX_ZOFF);
+    chtmp->rx.c[1].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2RX_Z1+0x1f*4);
+    chtmp->rx.c[1].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B2RX_ZOFF);
+    chtmp->rx.z2=hfc_B_SUB_VAL;
+    chtmp->rx.diff=0;
+
+    chtmp->tx.c[0].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1TX_Z1+0x1f*4);
+    chtmp->tx.c[0].z2p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1TX_Z2+0x1f*4);
+    chtmp->tx.c[0].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B1TX_ZOFF);
+    chtmp->tx.c[0].filled=0;
+    chtmp->tx.c[1].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2TX_Z1+0x1f*4);
+    chtmp->tx.c[1].z2p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2TX_Z2+0x1f*4);
+    chtmp->tx.c[1].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B2TX_ZOFF);
+    chtmp->tx.c[1].filled=0;
+    chtmp->tx.z1=hfc_B_SUB_VAL;
+    chtmp->tx.diff=0;
+
+    hfc_dch_init(hfctmp);
+
+    chtmp->initialized=0;
+}
+
+static int hfc_bch_check(struct hfc_card *hfctmp){
+    struct bch *chtmp=&hfctmp->bch;
+    int x,r;
+
+    for(x=0;x<2;x++){
+	chtmp->tx.c[x].filled=(chtmp->tx.z1-*chtmp->tx.c[x].z2p+hfc_B_FIFO_SIZE)%hfc_B_FIFO_SIZE;
+	chtmp->rx.c[x].filled=(*chtmp->rx.c[x].z1p-chtmp->rx.z2+hfc_B_FIFO_SIZE)%hfc_B_FIFO_SIZE;
+    }
+    if(chtmp->fill_fifo){
+	chtmp->checkcnt++;
+	chtmp->checkcnt%=DAHDI_CHUNKSIZE;
+	r=!chtmp->checkcnt;
+    }else{
+	x=chtmp->tx.c[0].filled-chtmp->tx.c[1].filled;
+	if(abs(x-chtmp->tx.diff)>1){
+	    printk(KERN_CRIT "zaphfc[%d]: tx sync changed: %d, %d\n",hfctmp->cardno,chtmp->tx.c[0].filled,chtmp->tx.c[1].filled);
+	    chtmp->tx.diff=x;
+	}
+	r=chtmp->tx.c[0].filled<=DAHDI_CHUNKSIZE*jitterbuffer&&chtmp->tx.c[1].filled<=DAHDI_CHUNKSIZE*jitterbuffer;
+    }
+    return(r);
+}
+
+#define hfc_bch_inc_z(a,b) (a)=((a)-hfc_B_SUB_VAL+(b))%hfc_B_FIFO_SIZE+hfc_B_SUB_VAL
+
+static void hfc_bch_tx(struct hfc_card *hfctmp){
+    struct bch *chtmp=&hfctmp->bch;
+    int x;
+
+    for(x=0;x<2;x++)
+	memcpy((void *)(chtmp->tx.c[x].fifo_base+chtmp->tx.z1),hfctmp->ztdev->chans[x].writechunk,DAHDI_CHUNKSIZE);
+    hfc_bch_inc_z(chtmp->tx.z1,DAHDI_CHUNKSIZE);
+    if(chtmp->fill_fifo){
+	chtmp->fill_fifo--;
+    }else if(chtmp->tx.c[0].filled<=1||chtmp->tx.c[1].filled<=1){
+	chtmp->fill_fifo=jitterbuffer;
+	if(chtmp->initialized)
+	    printk(KERN_CRIT "zaphfc[%d]: b channel buffer underrun: %d, %d\n",hfctmp->cardno,chtmp->tx.c[0].filled,chtmp->tx.c[1].filled);
+    }
+    if(!chtmp->fill_fifo)
+	for(x=0;x<2;x++)*chtmp->tx.c[x].z1p=chtmp->tx.z1;
+}
+
+static void hfc_bch_rx(struct hfc_card *hfctmp){
+    struct bch *chtmp=&hfctmp->bch;
+    int x;
+
+    x=chtmp->rx.c[0].filled-chtmp->rx.c[1].filled;
+    if(abs(x-chtmp->rx.diff)>1){
+	printk(KERN_CRIT "zaphfc[%d]: rx sync changed: %d, %d\n",hfctmp->cardno,chtmp->rx.c[0].filled,chtmp->rx.c[1].filled);
+	chtmp->rx.diff=x;
+    }
+    if(chtmp->rx.c[0].filled>=DAHDI_CHUNKSIZE&&chtmp->rx.c[1].filled>=DAHDI_CHUNKSIZE){
+	if((chtmp->rx.c[0].filled>=DAHDI_CHUNKSIZE*(jitterbuffer+2)&&chtmp->rx.c[1].filled>=DAHDI_CHUNKSIZE*(jitterbuffer+2))||!chtmp->initialized){
+	    if(chtmp->initialized)
+		printk(KERN_CRIT "zaphfc[%d]: b channel buffer overflow: %d, %d\n",hfctmp->cardno,chtmp->rx.c[0].filled,chtmp->rx.c[1].filled);
+	    hfc_bch_inc_z(chtmp->rx.z2,chtmp->rx.c[0].filled-chtmp->rx.c[0].filled%DAHDI_CHUNKSIZE-DAHDI_CHUNKSIZE);
+	    chtmp->initialized=1;
+	}
+	for(x=0;x<2;x++){
+	    memcpy(hfctmp->ztdev->chans[x].readchunk,(void *)(chtmp->rx.c[x].fifo_base+chtmp->rx.z2),DAHDI_CHUNKSIZE);
+	    dahdi_ec_chunk(&hfctmp->ztdev->chans[x],hfctmp->ztdev->chans[x].readchunk,hfctmp->ztdev->chans[x].writechunk);
+	}
+	hfc_bch_inc_z(chtmp->rx.z2,DAHDI_CHUNKSIZE);
+    }
+}
+
+/*===========================================================================*/
+
+static void hfc_dch_tx(struct hfc_card *hfctmp){
+    struct dch *chtmp=&hfctmp->dch;
+    u8 tx_f2_v;
+    u16 x;
+
+    if(hfctmp->ztdev->chans[2].bytes2transmit){
+	if(debug){
+	    printk(KERN_CRIT "zaphfc[%d]: card TX [ ",hfctmp->cardno);
+	    for(x=0;x<hfctmp->ztdev->chans[2].bytes2transmit;x++){
+		printk("%#2x ",hfctmp->dtransbuf[x]);
+	    }
+	    printk("] %d bytes\n",hfctmp->ztdev->chans[2].bytes2transmit);
+	}
+	tx_f2_v=*chtmp->tx.f2.p;
+	if(!(tx_f2_v-chtmp->tx.f1.v+hfc_MAX_DFRAMES+1-1)&(hfc_MAX_DFRAMES+1-1)){
+	    printk(KERN_CRIT "zaphfc[%d]: dchan tx fifo total number of frames exceeded!\n",hfctmp->cardno);
+	}else{
+	    if(((*(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z2+tx_f2_v*4)-chtmp->tx.f1.z1.v+hfc_D_FIFO_SIZE-1)&(hfc_D_FIFO_SIZE-1))<hfctmp->ztdev->chans[2].bytes2transmit){
+		printk(KERN_CRIT "zaphfc[%d]: dchan tx fifo not enough space for frame!\n",hfctmp->cardno);
+	    }else{
+		chtmp->tx.f1.v=((chtmp->tx.f1.v+1)&hfc_MAX_DFRAMES)|(hfc_MAX_DFRAMES+1);
+		x=min(hfctmp->ztdev->chans[2].bytes2transmit,hfc_D_FIFO_SIZE-chtmp->tx.f1.z1.v);
+		memcpy(hfctmp->fifos+hfc_FIFO_DTX_ZOFF+chtmp->tx.f1.z1.v,hfctmp->ztdev->chans[2].writechunk,x);
+		memcpy(hfctmp->fifos+hfc_FIFO_DTX_ZOFF,hfctmp->ztdev->chans[2].writechunk+x,hfctmp->ztdev->chans[2].bytes2transmit-x);
+		*(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z2+chtmp->tx.f1.v*4)=chtmp->tx.f1.z1.v;
+		chtmp->tx.f1.z1.v=(chtmp->tx.f1.z1.v+hfctmp->ztdev->chans[2].bytes2transmit+hfc_D_FIFO_SIZE)&(hfc_D_FIFO_SIZE-1);
+		*(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z1+chtmp->tx.f1.v*4)=chtmp->tx.f1.z1.v;
+		*chtmp->tx.f1.p=chtmp->tx.f1.v;
+	    }
+	}
+    }
+}
+
+static void hfc_dch_rx(struct hfc_card *hfctmp){
+    struct dch *chtmp=&hfctmp->dch;
+    u16 size;
+
+    hfctmp->ztdev->chans[2].bytes2receive=0;
+    hfctmp->ztdev->chans[2].eofrx=0;
+    if(*chtmp->rx.f1.p==chtmp->rx.f2.v){
+	hfctmp->regs.int_drec=0;
+    }else{
+	size=((*(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DRX_Z1+chtmp->rx.f2.v*4)-chtmp->rx.f2.z2.v+hfc_D_FIFO_SIZE)&(hfc_D_FIFO_SIZE-1))+1;
+	if(size<4){
+	    printk(KERN_CRIT "zaphfc[%d]: empty HDLC frame received.\n",hfctmp->cardno);
+	}else{
+	    u16 x=min(size,(u16)(hfc_D_FIFO_SIZE-chtmp->rx.f2.z2.v));
+	    memcpy(hfctmp->drecbuf,hfctmp->fifos+hfc_FIFO_DRX_ZOFF+chtmp->rx.f2.z2.v,x);
+	    memcpy(hfctmp->drecbuf+x,hfctmp->fifos+hfc_FIFO_DRX_ZOFF,size-x);
+	    if(hfctmp->drecbuf[size-1]){
+		printk(KERN_CRIT "zaphfc[%d]: received d channel frame with bad CRC.\n",hfctmp->cardno);
+	    }else{
+		hfctmp->ztdev->chans[2].bytes2receive=size-1;
+		hfctmp->ztdev->chans[2].eofrx=1;
+	    }
+	}
+	chtmp->rx.f2.z2.v=(chtmp->rx.f2.z2.v+size)&(hfc_D_FIFO_SIZE-1);
+	chtmp->rx.f2.v=((chtmp->rx.f2.v+1)&hfc_MAX_DFRAMES)|(hfc_MAX_DFRAMES+1);
+    }
+}
+
+DAHDI_IRQ_HANDLER(hfc_interrupt) {
+    struct hfc_card *hfctmp = dev_id;
+    struct hfc_card *hfctmp2;
+    struct dahdi_hfc *zthfc;
+    unsigned char stat, s1, s2, l1state;
+    unsigned long flags = 0;
+    unsigned long flags2 = 0;
+    int x;
+
+    if (!hfctmp) {
+	    return IRQ_NONE;
+    }
+
+    if (!hfctmp->pci_io) {
+	    printk(KERN_WARNING "%s: IO-mem disabled, cannot handle interrupt\n",
+		   __FUNCTION__);
+	    return IRQ_NONE;
+    }
+    
+    spin_lock_irqsave(&hfctmp->lock, flags);
+    stat = hfc_inb(hfctmp, hfc_STATUS);
+    if ((stat & hfc_STATUS_ANYINT) == 0) {
+        // maybe we are sharing the irq
+	spin_unlock_irqrestore(&hfctmp->lock,flags);
+	return IRQ_NONE;
+    }
+
+    s1 = hfc_inb(hfctmp, hfc_INT_S1);
+    s2 = hfc_inb(hfctmp, hfc_INT_S2); 
+    if (s1 != 0) {
+	if (s1 & hfc_INTS_TIMER) {
+	    // timer (bit 7)
+	    // printk(KERN_CRIT "timer %d %d %d.\n", stat, s1, s2);
+	}
+	if (s1 & hfc_INTS_L1STATE) {
+	    // state machine (bit 6)
+	    // printk(KERN_CRIT "zaphfc: layer 1 state machine interrupt\n");
+	    zthfc = hfctmp->ztdev;
+	    l1state = hfc_inb(hfctmp,hfc_STATES)  & hfc_STATES_STATE_MASK;
+	    if (hfctmp->regs.nt_mode == 1) {
+		if (debug) {
+	    	    printk(KERN_CRIT "zaphfc: card %d layer 1 state = G%d\n", hfctmp->cardno, l1state);
+		}
+		switch (l1state) {
+		    case 3:
+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d)", hfctmp->cardno, l1state);
+			break;
+		    default:
+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d)", hfctmp->cardno, l1state);
+		}
+		if (l1state == 2) {
+		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_ACTIVATE | hfc_STATES_DO_ACTION | hfc_STATES_NT_G2_G3);
+		} else if (l1state == 3) {
+		    // fix to G3 state (see specs)
+		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_LOAD_STATE | 3);
+		}
+	    } else {
+		if (debug) {
+	    	    printk(KERN_CRIT "zaphfc: card %d layer 1 state = F%d\n", hfctmp->cardno, l1state);
+		}
+		switch (l1state) {
+		    case 7:
+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d)", hfctmp->cardno, l1state);
+			break;
+		    default:
+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d)", hfctmp->cardno, l1state);
+		}
+		if (l1state == 3) {
+		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
+		}
+	    }
+	    
+	}
+	if (s1 & hfc_INTS_DREC) {
+	    // D chan RX (bit 5)
+	    hfctmp->regs.int_drec = 1;
+	    // mr. zapata there is something for you!
+	//    printk(KERN_CRIT "d chan rx\n");		    
+	}
+	if (s1 & hfc_INTS_B2REC) {
+	    // B2 chan RX (bit 4)
+	}
+	if (s1 & hfc_INTS_B1REC) {
+	    // B1 chan RX (bit 3)
+	}
+	if (s1 & hfc_INTS_DTRANS) {
+	    // D chan TX (bit 2)
+//	    printk(KERN_CRIT "zaphfc: dchan frame transmitted.\n");
+	}
+	if (s1 & hfc_INTS_B2TRANS) {
+	    // B2 chan TX (bit 1)
+	}
+	if (s1 & hfc_INTS_B1TRANS) {
+	    // B1 chan TX (bit 0)
+	}
+    }
+    if (s2 != 0) {
+	if (s2 & hfc_M2_PMESEL) {
+	    // kaboom irq (bit 7)
+	    //printk(KERN_CRIT "zaphfc: sync lost, pci performance too low. you might have some cpu throtteling enabled.\n");
+	}
+	if (s2 & hfc_M2_GCI_MON_REC) {
+	    // RxR monitor channel (bit 2)
+	}
+	if (s2 & hfc_M2_GCI_I_CHG) {
+	    // GCI I-change  (bit 1)
+	}
+	if((s2&hfc_M2_PROC_TRANS)&&(hfctmp->cardno==timer_card)){
+	    // processing/non-processing transition  (bit 0)
+	hfctmp2=hfctmp;
+	hfctmp=hfc_dev_list;
+	while(hfctmp){
+	    if(hfctmp->active){
+	    if(hfctmp!=hfctmp2)spin_lock_irqsave(&hfctmp->lock, flags2);
+	    if(hfc_bch_check(hfctmp)){
+    if (hfctmp->ztdev->span.flags & DAHDI_FLAG_RUNNING) {
+		    // clear dchan buffer
+	//	    memset(hfctmp->drecbuf, 0x0, sizeof(hfctmp->drecbuf));
+
+		    hfctmp->ztdev->chans[2].bytes2transmit = 0;
+		    hfctmp->ztdev->chans[2].maxbytes2transmit = hfc_D_FIFO_SIZE;
+
+		    dahdi_transmit(&(hfctmp->ztdev->span));
+
+		    hfc_bch_tx(hfctmp);
+		    hfc_dch_tx(hfctmp);
+		}
+
+		hfc_bch_rx(hfctmp);
+		if (hfctmp->regs.int_drec) {
+		    // dchan data to read
+		    hfc_dch_rx(hfctmp);
+		    if (hfctmp->ztdev->chans[2].bytes2receive > 0) {
+			    if (debug) {
+    				printk(KERN_CRIT "zaphfc: card %d RX [ ", hfctmp->cardno);
+				if (hfctmp->ztdev->chans[2].eofrx) {
+				    /* dont output CRC == less user confusion */
+				    for (x=0; x < hfctmp->ztdev->chans[2].bytes2receive - 2; x++) {
+					printk("%#2x ", hfctmp->drecbuf[x]);
+				    }
+				    printk("] %d bytes\n", hfctmp->ztdev->chans[2].bytes2receive - 2);
+				} else {
+				    for (x=0; x < hfctmp->ztdev->chans[2].bytes2receive; x++) {
+					printk("%#2x ", hfctmp->drecbuf[x]);
+				    }
+				    printk("..] %d bytes\n", hfctmp->ztdev->chans[2].bytes2receive);
+				}
+			    }
+		    }
+		} else {
+			// hmm....ok, let DAHDI receive nothing
+		    hfctmp->ztdev->chans[2].bytes2receive = 0;
+		}
+		if (hfctmp->ztdev->span.flags & DAHDI_FLAG_RUNNING) {
+		    dahdi_receive(&(hfctmp->ztdev->span));
+		}
+	    }
+	    if(hfctmp!=hfctmp2)spin_unlock_irqrestore(&hfctmp->lock,flags2);
+	    }
+	    hfctmp=hfctmp->next;
+	}
+	hfctmp=hfctmp2;
+	}
+    }
+    spin_unlock_irqrestore(&hfctmp->lock,flags);
+    return IRQ_RETVAL(1);
+}
+
+
+static int zthfc_open(struct dahdi_chan *chan) {
+    struct dahdi_hfc *zthfc = chan->pvt;
+    struct hfc_card *hfctmp = zthfc->card;
+    
+    if (!hfctmp) {
+    return 0;
+    }
+    try_module_get(THIS_MODULE);
+    return 0;
+}
+
+static int zthfc_close(struct dahdi_chan *chan) {
+    struct dahdi_hfc *zthfc = chan->pvt;
+    struct hfc_card *hfctmp = zthfc->card;
+
+    if (!hfctmp) {
+	return 0;
+    }
+
+    module_put(THIS_MODULE);
+    return 0;
+}
+
+static int zthfc_rbsbits(struct dahdi_chan *chan, int bits) {
+    return 0;
+}
+
+static int zthfc_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data) {
+        switch(cmd) {
+        default:
+                return -ENOTTY;
+        }
+        return 0;
+}
+
+static int zthfc_startup(struct dahdi_span *span) {
+    struct dahdi_hfc *zthfc = span->pvt;
+    struct hfc_card *hfctmp = zthfc->card;
+    int alreadyrunning;
+    
+    if (hfctmp == NULL) {
+	printk(KERN_INFO "zaphfc: no card for span at startup!\n");
+    }
+    alreadyrunning = span->flags & DAHDI_FLAG_RUNNING;
+    
+    if (alreadyrunning) return 0;
+
+    span->chans[2]->flags &= ~DAHDI_FLAG_HDLC;
+    span->chans[2]->flags |= DAHDI_FLAG_BRIDCHAN;
+
+    span->flags |= DAHDI_FLAG_RUNNING;
+
+    hfctmp->ticks = -2;
+    hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
+    hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
+
+    hfc_bch_init(hfctmp);
+
+    // drivers, start engines!
+    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
+    hfctmp->active=1;
+    return 0;
+}
+
+static int zthfc_shutdown(struct dahdi_span *span) {
+    return 0;
+}
+
+static int zthfc_maint(struct dahdi_span *span, int cmd) {
+    return 0;
+}
+
+static int zthfc_chanconfig(struct dahdi_chan *chan, int sigtype) {
+//    printk(KERN_CRIT "chan_config sigtype=%d\n", sigtype);
+    return 0;
+}
+
+static int zthfc_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc) {
+    span->lineconfig = lc->lineconfig;
+    return 0;
+}
+
+static int zthfc_initialize(struct dahdi_hfc *zthfc) {
+    struct hfc_card *hfctmp = zthfc->card;
+    int i;
+
+    memset(&zthfc->span, 0x0, sizeof(struct dahdi_span)); // you never can tell...
+
+    sprintf(zthfc->span.name, "ZTHFC%d", hfc_dev_count + 1);
+    if (hfctmp->regs.nt_mode == 1) {
+	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT]", hfc_dev_count + 1);
+	zthfc->span.spantype = "NT";
+    } else {
+	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE]", hfc_dev_count + 1);
+	zthfc->span.spantype = "TE";
+    }
+    zthfc->span.manufacturer = "Cologne Chips";
+    zthfc->span.spanconfig = zthfc_spanconfig;
+    zthfc->span.chanconfig = zthfc_chanconfig;
+    zthfc->span.startup = zthfc_startup;
+    zthfc->span.shutdown = zthfc_shutdown;
+    zthfc->span.maint = zthfc_maint;
+    zthfc->span.rbsbits = zthfc_rbsbits;
+    zthfc->span.open = zthfc_open;
+    zthfc->span.close = zthfc_close;
+    zthfc->span.ioctl = zthfc_ioctl;
+    zthfc->span.flags = 0;
+    zthfc->span.channels = 3;
+    zthfc->span.chans = zthfc->_chans;
+    for (i = 0; i < zthfc->span.channels; i++)
+	zthfc->_chans[i] = &zthfc->chans[i];
+    zthfc->span.offset = 0;
+    zthfc->span.irq = hfctmp->pcidev->irq; 
+
+    zthfc->span.deflaw = DAHDI_LAW_ALAW;
+    zthfc->span.linecompat = DAHDI_CONFIG_AMI | 
+			DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 | 
+			DAHDI_CONFIG_ESF | DAHDI_CONFIG_HDB3 |
+			DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
+    init_waitqueue_head(&zthfc->span.maintq);
+    zthfc->span.pvt = zthfc;
+    dahdi_copy_string(zthfc->span.devicetype, "HFC-S PCI-A", sizeof(zthfc->span.devicetype));
+    sprintf(zthfc->span.location, "PCI Bus %02d Slot %02d",
+			hfctmp->pcidev->bus->number, PCI_SLOT(hfctmp->pcidev->devfn) + 1);
+ 
+    for (i = 0; i < zthfc->span.channels; i++) {
+	memset(&(zthfc->chans[i]), 0x0, sizeof(struct dahdi_chan));
+	sprintf(zthfc->chans[i].name, "ZTHFC%d/%d/%d", hfc_dev_count + 1,0,i + 1);
+	zthfc->chans[i].pvt = zthfc;
+	zthfc->chans[i].sigcap =  DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS | DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_SF;
+	zthfc->chans[i].chanpos = i + 1; 
+    }
+
+    if (dahdi_register(&zthfc->span,0)) {
+	printk(KERN_CRIT "unable to register DAHDI device!\n");
+	return -1;
+    }
+//    printk(KERN_CRIT "zaphfc: registered DAHDI device!\n");
+    return 0;
+}
+
+int hfc_findCards(int pcivendor, int pcidevice, char *vendor_name, char *card_name) {
+    struct pci_dev *tmp;
+    struct hfc_card *hfctmp = NULL;
+    struct dahdi_hfc *zthfc = NULL;
+
+    tmp = pci_get_device(pcivendor, pcidevice, multi_hfc);
+    while (tmp != NULL) {
+	multi_hfc = tmp;	// skip this next time.
+
+	if (pci_enable_device(tmp)) {
+	    multi_hfc = NULL;
+	    return -1;
+	}
+	pci_set_master(tmp);
+
+	hfctmp = vmalloc(sizeof(struct hfc_card));
+	if (!hfctmp) {
+	    printk(KERN_WARNING "zaphfc: unable to vmalloc!\n");
+	    pci_disable_device(tmp);
+	    multi_hfc = NULL;
+	    return -ENOMEM;
+	}
+	memset(hfctmp, 0x0, sizeof(struct hfc_card));
+	spin_lock_init(&hfctmp->lock);
+	
+	hfctmp->active=0;
+	hfctmp->pcidev = tmp;
+	hfctmp->pcibus = tmp->bus->number;
+	hfctmp->pcidevfn = tmp->devfn; 
+
+	if (!tmp->irq) {
+	    printk(KERN_WARNING "zaphfc: no irq!\n");
+	} else {
+	    hfctmp->irq = tmp->irq;
+	}
+
+	hfctmp->pci_io = (char *) tmp->resource[1].start;
+	if (!hfctmp->pci_io) {
+	    printk(KERN_WARNING "zaphfc: no iomem!\n");
+	    vfree(hfctmp);
+	    pci_disable_device(tmp);
+	    multi_hfc = NULL;
+	    return -1;
+	}
+
+	hfctmp->fifos=(void *)__get_free_pages(GFP_KERNEL,log2(hfc_FIFO_MEM_SIZE_PAGES));
+	if (!hfctmp->fifos) {
+	    printk(KERN_WARNING "zaphfc: unable to __get_free_pages fifomem!\n");
+	    vfree(hfctmp);
+	    pci_disable_device(tmp);
+	    multi_hfc = NULL;
+	    return -ENOMEM;
+	} else {
+	    pci_write_config_dword(hfctmp->pcidev, 0x80, (u_int) virt_to_bus(hfctmp->fifos));
+	    hfctmp->pci_io = ioremap((ulong) hfctmp->pci_io, 256);
+	}
+
+	if (request_irq(hfctmp->irq, &hfc_interrupt, DAHDI_IRQ_SHARED, "zaphfc", hfctmp)) {
+	    printk(KERN_WARNING "zaphfc: unable to register irq\n");
+	    free_pages((unsigned long)hfctmp->fifos,log2(hfc_FIFO_MEM_SIZE_PAGES));
+	    vfree(hfctmp);
+	    iounmap((void *) hfctmp->pci_io);
+	    pci_disable_device(tmp);
+	    multi_hfc = NULL;
+	    return -EIO;
+	}
+
+	printk(KERN_INFO
+		       "zaphfc: %s %s configured at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n",
+			vendor_name, card_name,
+		       (u_int) hfctmp->pci_io,
+		       (u_int) hfctmp->fifos,
+		       (u_int) virt_to_bus(hfctmp->fifos),
+		       hfctmp->irq, HZ); 
+	pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY);	// enable memio
+	hfctmp->regs.int_m1 = 0;	// no ints
+	hfctmp->regs.int_m2 = 0;	// not at all
+	hfc_outb(hfctmp,hfc_INT_M1,hfctmp->regs.int_m1);
+	hfc_outb(hfctmp,hfc_INT_M2,hfctmp->regs.int_m2);
+
+	if ((modes & (1 << hfc_dev_count)) != 0) {
+	    printk(KERN_INFO "zaphfc: Card %d configured for NT mode\n",hfc_dev_count);
+	    hfctmp->regs.nt_mode = 1;
+	} else {
+	    printk(KERN_INFO "zaphfc: Card %d configured for TE mode\n",hfc_dev_count);
+	    hfctmp->regs.nt_mode = 0;
+	}
+
+	if(sync_slave&(1<<hfc_dev_count)){
+	    printk(KERN_INFO "zaphfc: Card %d configured for slave mode\n",hfc_dev_count);
+	    hfctmp->regs.mst_mode=hfc_MST_MODE_SLAVE|hfc_MST_MODE_F0_LONG_DURATION;
+	    hfctmp->regs.mst_emod=hfc_MST_EMOD_SLOW_CLOCK_ADJ;
+	}else{
+	    printk(KERN_INFO "zaphfc: Card %d configured for master mode\n",hfc_dev_count);
+	    hfctmp->regs.mst_mode=hfc_MST_MODE_MASTER|hfc_MST_MODE_F0_LONG_DURATION;
+	    hfctmp->regs.mst_emod=0;
+	}
+
+	zthfc = vmalloc(sizeof(struct dahdi_hfc));
+	if (!zthfc) {
+	    printk(KERN_CRIT "zaphfc: unable to vmalloc!\n");
+	    hfc_shutdownCard(hfctmp);
+	    vfree(hfctmp);
+	    multi_hfc = NULL;
+	    return -ENOMEM;
+	}
+	memset(zthfc, 0x0, sizeof(struct dahdi_hfc));
+
+	zthfc->card = hfctmp;
+	zthfc_initialize(zthfc);
+	hfctmp->ztdev = zthfc;
+
+	memset(hfctmp->drecbuf, 0x0, sizeof(hfctmp->drecbuf));
+	hfctmp->ztdev->chans[2].readchunk = hfctmp->drecbuf;
+
+	memset(hfctmp->dtransbuf, 0x0, sizeof(hfctmp->dtransbuf));
+	hfctmp->ztdev->chans[2].writechunk = hfctmp->dtransbuf;
+
+	memset(hfctmp->brecbuf[0], 0x0, sizeof(hfctmp->brecbuf[0]));
+	hfctmp->ztdev->chans[0].readchunk = hfctmp->brecbuf[0];
+	memset(hfctmp->btransbuf[0], 0x0, sizeof(hfctmp->btransbuf[0]));
+	hfctmp->ztdev->chans[0].writechunk = hfctmp->btransbuf[0];
+
+	memset(hfctmp->brecbuf[1], 0x0, sizeof(hfctmp->brecbuf[1]));
+	hfctmp->ztdev->chans[1].readchunk = hfctmp->brecbuf[1];
+	memset(hfctmp->btransbuf[1], 0x0, sizeof(hfctmp->btransbuf[1]));
+	hfctmp->ztdev->chans[1].writechunk = hfctmp->btransbuf[1];
+
+	hfc_registerCard(hfctmp);
+	hfc_resetCard(hfctmp);
+	tmp = pci_get_device(pcivendor, pcidevice, multi_hfc);
+    }
+    return 0;
+}
+
+int init_module(void) {
+    int i = 0;
+    if(jitterbuffer<1){
+	printk(KERN_INFO "zaphfc: invalid jitterbuffer size specified: %d - changing to minimum of 1\n",jitterbuffer);
+	jitterbuffer=1;
+    }else if(jitterbuffer>500){
+	printk(KERN_INFO "zaphfc: invalid jitterbuffer size specified: %d - changing to maximum of 500\n",jitterbuffer);
+	jitterbuffer=500;
+    }
+    printk(KERN_INFO "zaphfc: jitterbuffer size: %d\n",jitterbuffer);
+    while (id_list[i].vendor_id) {
+	multi_hfc = NULL;
+	hfc_findCards(id_list[i].vendor_id, id_list[i].device_id, id_list[i].vendor_name, id_list[i].card_name);
+	i++;
+    }
+    printk(KERN_INFO "zaphfc: %d hfc-pci card(s) in this box.\n", hfc_dev_count);
+    return 0;
+}
+
+void cleanup_module(void) {
+    struct hfc_card *tmpcard;
+
+    printk(KERN_INFO "zaphfc: stop\n");
+//    spin_lock(&registerlock);
+    tmpcard=hfc_dev_list;
+    while(tmpcard){
+	hfc_shutdownCard1(tmpcard);
+	tmpcard=tmpcard->next;
+    }
+    while (hfc_dev_list != NULL) {
+	if (hfc_dev_list == NULL) break;
+	hfc_shutdownCard2(hfc_dev_list);
+	tmpcard = hfc_dev_list;
+	hfc_dev_list = hfc_dev_list->next;
+	if (tmpcard != NULL) {
+	    vfree(tmpcard);
+	    tmpcard = NULL;
+	    printk(KERN_INFO "zaphfc: freed one card.\n");
+	}
+    }
+//    spin_unlock(&registerlock);
+}
+#endif
+
+
+module_param(modes, int, 0400);
+module_param(debug, int, 0600);
+module_param(sync_slave, int, 0400);
+module_param(timer_card, int, 0400);
+module_param(jitterbuffer, int, 0400);
+
+MODULE_DESCRIPTION("HFC-S PCI A Zaptel Driver");
+MODULE_AUTHOR("Klaus-Peter Junghanns <kpj@junghanns.net>");
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif	
diff -rupN originales/dahdi-linux-2.1.0.4/drivers/dahdi/zaphfc.h dahdi-linux-2.1.0.4/drivers/dahdi/zaphfc.h
--- originales/dahdi-linux-2.1.0.4/drivers/dahdi/zaphfc.h	1970-01-01 00:00:00.000000000 +0000
+++ dahdi-linux-2.1.0.4/drivers/dahdi/zaphfc.h	2009-04-08 04:36:12.000000000 +0100
@@ -0,0 +1,344 @@
+/*
+ * zaphfc.h - Zaptel driver for HFC-S PCI A based ISDN BRI cards
+ *
+ * kernel module based on HFC PCI ISDN4Linux and Zaptel drivers
+ *
+ * Copyright (C) 2002, 2003, 2004, 2005 Junghanns.NET GmbH
+ *
+ * Klaus-Peter Junghanns <kpj@junghanns.net>
+ *
+ * This program is free software and may be modified and
+ * distributed under the terms of the GNU Public License.
+ *
+ */
+
+/* HFC register addresses - accessed using memory mapped I/O */
+/* For a list, see datasheet section 3.2.1 at page 21 */
+
+#define hfc_outb(a,b,c) (writeb((c),(a)->pci_io+(b)))
+#define hfc_inb(a,b) (readb((a)->pci_io+(b)))
+
+/* GCI/IOM bus monitor registers */
+
+#define hfc_C_I       0x08
+#define hfc_TRxR      0x0C
+#define hfc_MON1_D    0x28
+#define hfc_MON2_D    0x2C
+
+
+/* GCI/IOM bus timeslot registers */
+
+#define hfc_B1_SSL    0x80
+#define hfc_B2_SSL    0x84
+#define hfc_AUX1_SSL  0x88
+#define hfc_AUX2_SSL  0x8C
+#define hfc_B1_RSL    0x90
+#define hfc_B2_RSL    0x94
+#define hfc_AUX1_RSL  0x98
+#define hfc_AUX2_RSL  0x9C
+
+/* GCI/IOM bus data registers */
+
+#define hfc_B1_D      0xA0
+#define hfc_B2_D      0xA4
+#define hfc_AUX1_D    0xA8
+#define hfc_AUX2_D    0xAC
+
+/* GCI/IOM bus configuration registers */
+
+#define hfc_MST_EMOD  0xB4
+#define hfc_MST_MODE	 0xB8
+#define hfc_CONNECT 	 0xBC
+
+
+/* Interrupt and status registers */
+
+#define hfc_FIFO_EN   0x44
+#define hfc_TRM       0x48
+#define hfc_B_MODE    0x4C
+#define hfc_CHIP_ID   0x58
+#define hfc_CIRM  	 0x60
+#define hfc_CTMT	 0x64
+#define hfc_INT_M1  	 0x68
+#define hfc_INT_M2  	 0x6C
+#define hfc_INT_S1  	 0x78
+#define hfc_INT_S2  	 0x7C
+#define hfc_STATUS  	 0x70
+
+/* S/T section registers */
+
+#define hfc_STATES  	 0xC0
+#define hfc_SCTRL  	 0xC4
+#define hfc_SCTRL_E   0xC8
+#define hfc_SCTRL_R   0xCC
+#define hfc_SQ  	 0xD0
+#define hfc_CLKDEL  	 0xDC
+#define hfc_B1_REC    0xF0
+#define hfc_B1_SEND   0xF0
+#define hfc_B2_REC    0xF4
+#define hfc_B2_SEND   0xF4
+#define hfc_D_REC     0xF8
+#define hfc_D_SEND    0xF8
+#define hfc_E_REC     0xFC
+
+/* Bits and values in various HFC PCI registers */
+
+/* bits in status register (READ) */
+#define hfc_STATUS_PCI_PROC   0x02
+#define hfc_STATUS_NBUSY	  0x04 
+#define hfc_STATUS_TIMER_ELAP 0x10
+#define hfc_STATUS_STATINT	  0x20
+#define hfc_STATUS_FRAMEINT	  0x40
+#define hfc_STATUS_ANYINT	  0x80
+
+/* bits in CTMT (Write) */
+#define hfc_CTMT_CLTIMER    0x80
+#define hfc_CTMT_TIM3_125   0x04
+#define hfc_CTMT_TIM25      0x10
+#define hfc_CTMT_TIM50      0x14
+#define hfc_CTMT_TIM400     0x18
+#define hfc_CTMT_TIM800     0x1C
+#define hfc_CTMT_AUTO_TIMER 0x20
+#define hfc_CTMT_TRANSB2    0x02
+#define hfc_CTMT_TRANSB1    0x01
+
+/* bits in CIRM (Write) */
+#define hfc_CIRM_AUX_MSK    0x07
+#define hfc_CIRM_RESET  	  0x08
+#define hfc_CIRM_B1_REV     0x40
+#define hfc_CIRM_B2_REV     0x80
+
+/* bits in INT_M1 and INT_S1 */
+#define hfc_INTS_B1TRANS  0x01
+#define hfc_INTS_B2TRANS  0x02
+#define hfc_INTS_DTRANS   0x04
+#define hfc_INTS_B1REC    0x08
+#define hfc_INTS_B2REC    0x10
+#define hfc_INTS_DREC     0x20
+#define hfc_INTS_L1STATE  0x40
+#define hfc_INTS_TIMER    0x80
+
+/* bits in INT_M2 */
+#define hfc_M2_PROC_TRANS    0x01
+#define hfc_M2_GCI_I_CHG     0x02
+#define hfc_M2_GCI_MON_REC   0x04
+#define hfc_M2_IRQ_ENABLE    0x08
+#define hfc_M2_PMESEL        0x80
+
+/* bits in STATES */
+#define hfc_STATES_STATE_MASK     0x0F
+#define hfc_STATES_LOAD_STATE    0x10
+#define hfc_STATES_ACTIVATE	     0x20
+#define hfc_STATES_DO_ACTION     0x40
+#define hfc_STATES_NT_G2_G3      0x80
+
+/* bits in HFCD_MST_MODE */
+#define hfc_MST_MODE_MASTER	     0x01
+#define hfc_MST_MODE_SLAVE         0x00
+#define hfc_MST_MODE_F0_LONG_DURATION         0x08
+/* remaining bits are for codecs control */
+
+/* bits in HFCD_MST_EMOD */
+#define hfc_MST_EMOD_SLOW_CLOCK_ADJ	0x01
+
+/* bits in HFCD_SCTRL */
+#define hfc_SCTRL_B1_ENA	     0x01
+#define hfc_SCTRL_B2_ENA	     0x02
+#define hfc_SCTRL_MODE_TE        0x00
+#define hfc_SCTRL_MODE_NT        0x04
+#define hfc_SCTRL_LOW_PRIO	     0x08
+#define hfc_SCTRL_SQ_ENA	     0x10
+#define hfc_SCTRL_TEST	     0x20
+#define hfc_SCTRL_NONE_CAP	     0x40
+#define hfc_SCTRL_PWR_DOWN	     0x80
+
+/* bits in SCTRL_E  */
+#define hfc_SCTRL_E_AUTO_AWAKE    0x01
+#define hfc_SCTRL_E_DBIT_1        0x04
+#define hfc_SCTRL_E_IGNORE_COL    0x08
+#define hfc_SCTRL_E_CHG_B1_B2     0x80
+
+/* bits in FIFO_EN register */
+#define hfc_FIFOEN_B1TX   0x01
+#define hfc_FIFOEN_B1RX   0x02
+#define hfc_FIFOEN_B2TX   0x04
+#define hfc_FIFOEN_B2RX   0x08
+#define hfc_FIFOEN_DTX    0x10
+#define hfc_FIFOEN_DRX    0x20
+
+#define hfc_FIFOEN_B1     (hfc_FIFOEN_B1TX|hfc_FIFOEN_B1RX)
+#define hfc_FIFOEN_B2     (hfc_FIFOEN_B2TX|hfc_FIFOEN_B2RX)
+#define hfc_FIFOEN_D      (hfc_FIFOEN_DTX|hfc_FIFOEN_DRX)
+
+/* bits in the CONNECT register */
+#define hfc_CONNECT_B1_shift	0
+#define hfc_CONNECT_B2_shift	3
+
+#define	hfc_CONNECT_HFC_from_ST		0x0
+#define hfc_CONNECT_HFC_from_GCI	0x1
+#define hfc_CONNECT_ST_from_HFC		0x0
+#define hfc_CONNECT_ST_from_GCI		0x2
+#define hfc_CONNECT_GCI_from_HFC	0x0
+#define	hfc_CONNECT_GCI_from_ST		0x4
+
+/* bits in the __SSL and __RSL registers */
+#define	hfc_SRSL_STIO	0x40
+#define hfc_SRSL_ENABLE	0x80
+#define hfc_SRCL_SLOT_MASK	0x1f
+
+/* FIFO memory definitions */
+
+#define hfc_FMASK	0x000f
+#define hfc_ZMASK	0x01ff
+#define hfc_ZMASKB	0x1fff
+
+#define hfc_D_FIFO_SIZE	0x0200
+#define hfc_B_SUB_VAL	0x0200
+#define hfc_B_FIFO_SIZE	0x1E00
+#define hfc_MAX_DFRAMES	0x000f
+
+#define hfc_FIFO_DTX_Z1	0x2080
+#define hfc_FIFO_DTX_Z2 0x2082
+#define hfc_FIFO_DTX_F1	0x20a0
+#define hfc_FIFO_DTX_F2	0x20a1
+#define hfc_FIFO_DTX	0x0000
+#define hfc_FIFO_DTX_ZOFF	0x000
+
+#define hfc_FIFO_DRX_Z1	0x6080
+#define hfc_FIFO_DRX_Z2 0x6082
+#define hfc_FIFO_DRX_F1	0x60a0
+#define hfc_FIFO_DRX_F2	0x60a1
+#define hfc_FIFO_DRX	0x4000
+#define hfc_FIFO_DRX_ZOFF	0x4000
+
+#define hfc_FIFO_B1TX_Z1	0x2000
+#define hfc_FIFO_B1TX_Z2 	0x2002
+#define hfc_FIFO_B1RX_Z1	0x6000
+#define hfc_FIFO_B1RX_Z2 	0x6002
+
+#define hfc_FIFO_B1TX_F1	0x2080
+#define hfc_FIFO_B1TX_F2	0x2081
+#define hfc_FIFO_B1RX_F1	0x6080
+#define hfc_FIFO_B1RX_F2	0x6081
+
+#define hfc_FIFO_B1RX_ZOFF	0x4000
+#define hfc_FIFO_B1TX_ZOFF	0x0000
+
+#define hfc_FIFO_B2TX_Z1	0x2100
+#define hfc_FIFO_B2TX_Z2 	0x2102
+#define hfc_FIFO_B2RX_Z1	0x6100
+#define hfc_FIFO_B2RX_Z2 	0x6102
+
+#define hfc_FIFO_B2TX_F1	0x2180
+#define hfc_FIFO_B2TX_F2	0x2181
+#define hfc_FIFO_B2RX_F1	0x6180
+#define hfc_FIFO_B2RX_F2	0x6181
+
+#define hfc_FIFO_B2RX_ZOFF	0x6000
+#define hfc_FIFO_B2TX_ZOFF	0x2000
+
+#define hfc_BTRANS_THRESHOLD 128
+#define hfc_BTRANS_THRESMASK 0x00
+
+#define hfc_FIFO_MEM_SIZE_BYTES (32*1024)
+#define hfc_FIFO_MEM_SIZE_PAGES ((hfc_FIFO_MEM_SIZE_BYTES+PAGE_SIZE-1)/PAGE_SIZE)
+
+/* Structures */
+
+typedef struct hfc_regs {
+    unsigned char fifo_en;
+    unsigned char ctmt;
+    unsigned char int_m1;
+    unsigned char int_m2;
+    unsigned char sctrl;
+    unsigned char sctrl_e;
+    unsigned char sctrl_r;
+    unsigned char connect;
+    unsigned char trm;
+    unsigned char mst_mode;
+    unsigned char mst_emod;
+    unsigned char bswapped;
+    unsigned char nt_mode;
+    unsigned char int_drec;
+} hfc_regs;
+
+struct bch {
+    int fill_fifo,checkcnt,initialized;
+    struct {
+	u16 z2;
+	struct {
+	    volatile u16 *z1p;
+	    volatile u8 *fifo_base;
+	    int filled;
+	} c[2];
+	int diff;
+    } rx;
+    struct {
+	u16 z1;
+	struct {
+	    volatile u16 *z1p,*z2p;
+	    volatile u8 *fifo_base;
+	    int filled;
+	} c[2];
+	int diff;
+    } tx;
+};
+
+struct dch {
+    struct {
+	struct {
+	    volatile u8 *p;
+	} f1;
+	struct {
+	    u8 v;
+	    struct {
+		u16 v;
+	    } z2;
+	} f2;
+    } rx;
+    struct {
+	struct {
+	    u8 v;
+	    volatile u8 *p;
+	    struct {
+		u16 v;
+	    } z1;
+	} f1;
+	struct {
+	    volatile u8 *p;
+	} f2;
+    } tx;
+};
+
+typedef struct hfc_card {
+    spinlock_t lock;
+    unsigned int irq;
+    unsigned int iomem;
+    int ticks;		
+    unsigned char *pci_io;
+    void *fifos;		// 32k aligned mem for the fifos
+    struct hfc_regs regs;
+    unsigned int pcibus;
+    unsigned int pcidevfn;
+    struct pci_dev *pcidev;
+    struct dahdi_hfc *ztdev;
+    int	drecinframe;
+    unsigned char drecbuf[hfc_D_FIFO_SIZE];
+    unsigned char dtransbuf[hfc_D_FIFO_SIZE];
+    unsigned char brecbuf[2][DAHDI_CHUNKSIZE];
+    unsigned char btransbuf[2][DAHDI_CHUNKSIZE];
+    unsigned char cardno;
+    int active;
+    struct bch bch;
+    struct dch dch;
+    struct hfc_card *next;
+} hfc_card;
+
+typedef struct dahdi_hfc {
+    unsigned int usecount;
+    struct dahdi_span span;
+    struct dahdi_chan chans[3];
+    struct dahdi_chan *_chans[3];
+    struct hfc_card *card;
+} dahdi_hfc;
+
diff -rupN originales/dahdi-linux-2.1.0.4/include/dahdi/kernel.h dahdi-linux-2.1.0.4/include/dahdi/kernel.h
--- originales/dahdi-linux-2.1.0.4/include/dahdi/kernel.h	2009-01-28 02:55:34.000000000 +0000
+++ dahdi-linux-2.1.0.4/include/dahdi/kernel.h	2009-04-08 12:42:02.000000000 +0100
@@ -139,6 +139,13 @@ struct dahdi_chan {
 	int do_ppp_error;
 	struct sk_buff_head ppp_rq;
 #endif
+#ifdef CONFIG_DAHDI_BRI_DCHANS
+	int bytes2receive;
+	int maxbytes2transmit; /* size of the tx buffer in the card driver */
+	int bytes2transmit;
+	int eofrx;
+	int eoftx;
+#endif
 	spinlock_t lock;
 	char name[40];
 	/* Specified by DAHDI */
@@ -469,6 +476,9 @@ enum {
 	DAHDI_FLAGBIT_LOOPED	= 18,	/*!< Loopback the receive data from the channel to the transmit */
 	DAHDI_FLAGBIT_MTP2	= 19,	/*!< Repeats last message in buffer and also discards repeating messages sent to us */
 	DAHDI_FLAGBIT_HDLC56	= 20,	/*!< Sets the given channel (if in HDLC mode) to use 56K HDLC instead of 64K  */
+#if defined(CONFIG_DAHDI_BRI_DCHANS)
+	DAHDI_FLAGBIT_BRIDCHAN   = 21,	/*!< hardhdlc-like handling of the D channel */
+#endif
 };
 
 /* map flagbits to flag masks */
@@ -507,6 +517,7 @@ enum {
 #define DAHDI_FLAG_LOOPED	DAHDI_FLAG(LOOPED)
 #define DAHDI_FLAG_MTP2		DAHDI_FLAG(MTP2)
 #define DAHDI_FLAG_HDLC56	DAHDI_FLAG(HDLC56)
+#define DAHDI_FLAG_BRIDCHAN	DAHDI_FLAG(BRIDCHAN)
 
 struct dahdi_span {
 	spinlock_t lock;
