diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2009-04-30 12:13:00 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2009-04-30 12:13:00 +0000 |
commit | de3d910658f394a7ac7ad86cae13005856d9b7f2 (patch) | |
tree | d1ad13e5a9d101a0150796e869850d7aded4da1e /extra | |
parent | 73fabdb4e43466a9f3a0777780045e3d83274d0c (diff) | |
download | aports-de3d910658f394a7ac7ad86cae13005856d9b7f2.tar.bz2 aports-de3d910658f394a7ac7ad86cae13005856d9b7f2.tar.xz |
extra/dahdi-linux: patch for HFC-4S cards
from here:
http://bugs.digium.com/view.php?id=13897
Diffstat (limited to 'extra')
-rw-r--r-- | extra/dahdi-linux/APKBUILD | 6 | ||||
-rw-r--r-- | extra/dahdi-linux/dahdi-linux-2.1.0.4-hfc-4s.patch | 556 |
2 files changed, 560 insertions, 2 deletions
diff --git a/extra/dahdi-linux/APKBUILD b/extra/dahdi-linux/APKBUILD index b13ab22a33..80121e1b0a 100644 --- a/extra/dahdi-linux/APKBUILD +++ b/extra/dahdi-linux/APKBUILD @@ -4,7 +4,7 @@ pkgname=dahdi-linux _kernflavor=grsec _kernver=2.6.28.9 pkgver=2.1.0.4 -pkgrel=6 +pkgrel=7 pkgdesc="Digium Asterisk Hardware Device Interface drivers" url="http://www.asterisk.org" license="GPL" @@ -19,6 +19,7 @@ source="http://downloads.digium.com/pub/telephony/dahdi-linux/releases/$pkgname- dahdi-bri_dchan.patch dahdi-zaphfc.patch zaphfc-dahdi-flortz.diff + $pkgname-2.1.0.4-hfc-4s.patch " build() { @@ -51,4 +52,5 @@ md5sums="ef2d34c394e8b600ad392560efc56920 dahdi-linux-2.1.0.4.tar.gz c78fb8d80f9efdffd950297c88ff9273 dahdi-depmod.patch 1c9c44497fc883c6a5381abc93e5e6cf dahdi-bri_dchan.patch a822c092f0548cd13f5e8d8cba053af6 dahdi-zaphfc.patch -291c5c44c86ab02443a742415461ddca zaphfc-dahdi-flortz.diff" +291c5c44c86ab02443a742415461ddca zaphfc-dahdi-flortz.diff +b01c57444be3a87f6f71dd71c4451ec7 dahdi-linux-2.1.0.4-hfc-4s.patch" diff --git a/extra/dahdi-linux/dahdi-linux-2.1.0.4-hfc-4s.patch b/extra/dahdi-linux/dahdi-linux-2.1.0.4-hfc-4s.patch new file mode 100644 index 0000000000..e6011a4038 --- /dev/null +++ b/extra/dahdi-linux/dahdi-linux-2.1.0.4-hfc-4s.patch @@ -0,0 +1,556 @@ +diff -rupN /drivers/dahdi/wcb4xxp/base.c /usr/src/dahdi-linux-2.1.0.4/drivers/dahdi/wcb4xxp/base.c +--- a/drivers/dahdi/wcb4xxp/base.c 2008-12-17 15:57:56.000000000 +0000 ++++ b/drivers/dahdi/wcb4xxp/base.c 2009-03-10 00:47:02.000000000 +0000 +@@ -75,7 +75,7 @@ + #define DBG_SPANFILTER ((1 << bspan->port) & spanfilter) + + static int debug = 0; +-static int spanfilter = 15; ++static int spanfilter = 255; /* Bitmap .. 1, 2, 4, 8, 16, 32, 64, 128 for ports 1-8 */ + #ifdef LOOPBACK_SUPPORTED + static int loopback = 0; + #endif +@@ -110,10 +110,21 @@ static struct proc_dir_entry *myproc; + struct devtype { + char *desc; + unsigned int flags; ++ int ports; /* Number of ports the card has */ ++ int has_ec; /* Does the card have an Echo Canceller */ ++ enum cards_ids card_type; /* Card type - Digium B410P, ... */ + }; + +-static struct devtype wcb4xxp = { "Wildcard B410P", 0 }; +- ++static struct devtype wcb4xxp = { "Wildcard B410P", .ports = 4, .has_ec = 1, .card_type = B410P }; ++static struct devtype hfc2s = { "HFC-2S Junghanns.NET duoBRI PCI", .ports = 2, .has_ec = 0, .card_type = DUOBRI }; ++static struct devtype hfc4s = { "HFC-4S Junghanns.NET quadBRI PCI", .ports = 4, .has_ec = 0, .card_type = QUADBRI }; ++static struct devtype hfc8s = { "HFC-4S Junghanns.NET octoBRI PCI", .ports = 8, .has_ec = 0, .card_type = OCTOBRI }; ++static struct devtype hfc2s_OV ={ "OpenVox B200P", .ports = 2, .has_ec = 0, .card_type = B200P_OV }; ++static struct devtype hfc4s_OV ={ "OpenVox B400P", .ports = 4, .has_ec = 0, .card_type = B400P_OV }; ++static struct devtype hfc8s_OV ={ "OpenVox B800P", .ports = 8, .has_ec = 0, .card_type = B800P_OV }; ++static struct devtype hfc2s_BN ={ "BeroNet BN2S0", .ports = 2, .has_ec = 0, .card_type = BN2S0 }; ++static struct devtype hfc4s_BN ={ "BeroNet BN4S0", .ports = 4, .has_ec = 0, .card_type = BN4S0 }; ++static struct devtype hfc8s_BN ={ "BeroNet BN8S0", .ports = 8, .has_ec = 0, .card_type = BN8S0 }; + + #if 0 + static const char *wcb4xxp_rcsdata = "$RCSfile: base.c,v $ $Revision: 5576 $"; +@@ -385,7 +396,14 @@ static void hfc_gpio_init(struct b4xxp * + + mb(); + +- b4xxp_setreg8(b4, R_GPIO_SEL, 0xf0); /* GPIO0..7 S/T, 8..15 GPIO */ ++ if ((b4->card_type == OCTOBRI) || (b4->card_type == B800P_OV) || (b4->card_type == BN8S0)) ++ { ++ b4xxp_setreg8(b4, R_GPIO_SEL, 0x00); /* GPIO0..15 S/T - HFC-8S uses GPIO8-15 for S/T ports 5-8 */ ++ } ++ else ++ { ++ b4xxp_setreg8(b4, R_GPIO_SEL, 0xf0); /* GPIO0..7 S/T, 8..15 GPIO */ ++ } + + mb(); + +@@ -600,13 +618,16 @@ static void ec_init(struct b4xxp *b4) + unsigned char b; + unsigned int i, j, mask; + ++ if (! b4->has_ec) /* Avoid Echo Cancelling for non hardware echo canceller cards */ ++ 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 +1011,15 @@ static void hfc_assign_dchan_fifo(struct + int fifo, hfc_chan; + unsigned long irq_flags; + +- fifo = port + 8; ++ if ((b4->card_type == B800P_OV) || (b4->card_type == OCTOBRI) || (b4->card_type == BN8S0)) ++ { ++ fifo = port + 16; /* In HFC-8S cards we can't use ports 8-11 for dchan FIFOs */ ++ } ++ else ++ { ++ fifo = port + 8; ++ } ++ + hfc_chan = (port * 4) + 2; + + /* record the host's FIFO # in the span fifo array */ +@@ -1192,7 +1221,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 +1423,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 +1793,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 has 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) ++ 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 +1832,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 +1847,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) && (b4->has_ec)) { + hfc_assign_bchan_fifo_ec(b4, span, 0); + hfc_assign_bchan_fifo_ec(b4, span, 1); + } else { +@@ -1835,6 +1900,145 @@ 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; ++ unsigned long leddw; ++ int i,j; ++ struct b4xxp_span *bspan; ++ lled = 0; ++ j=8; ++ ++ b4->blinktimer++; ++ for (i=0; i < 8; i++) { ++ bspan = &b4->spans[i]; ++ j = j -1 ; /* Leds are in reverse order - Led 7 => Port 0 */ ++ if (bspan->span.flags & DAHDI_FLAG_RUNNING) { ++ if (bspan->span.alarms) { ++ lled |= 1 << j; /* Led OFF in alarm state */ ++ } else if (bspan->span.mainttimer || bspan->span.maintstat) { ++ if (b4->blinktimer >= 0x7f) /* Led Blinking in maint state */ ++ { ++ lled |= 1 << j; ++ } ++ else ++ { ++ lled |= 0 << j; ++ } ++ } else { ++ ++ lled |= 0 << j; /* Led ON - No alarms */ ++ } ++ } ++ else ++ lled |= 1 << j; /* Led OFF - Not running */ ++ } ++ /* 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; ++ } ++} ++ ++static void b4xxp_update_leds_hfc(struct b4xxp *b4) ++{ ++ int i, leds; ++ int led[4]; ++ struct b4xxp_span *bspan; ++ ++ b4->blinktimer++; ++ for (i=0; i < b4->numspans; i++) { ++ bspan = &b4->spans[i]; ++ ++ if (bspan->span.flags & DAHDI_FLAG_RUNNING) { ++ if (bspan->span.alarms) { ++ if (b4->blinktimer >= 0x7f) /* Red blinking -> Alarm */ ++ { ++ led[i] = 2; ++ } ++ else ++ { ++ led[i] = 0; ++ } ++ } else if (bspan->span.mainttimer || bspan->span.maintstat) { ++ if (b4->blinktimer >= 0x7f) /* Green blinking -> Maint status */ ++ { ++ led[i] = 1; ++ } ++ else ++ { ++ led[i] = 0; ++ } ++ } else { ++ /* No Alarm - Green */ ++ led[i] = 1; ++ } ++ } ++ else ++ led[i] = 0; /* OFF - Not running */ ++ } ++ ++ /* Each card manage leds in a different way. So one section per card type */ ++ ++ if (b4->card_type == B400P_OV) { ++ leds = ((led[0] > 0) << 0) | ((led[1] > 0) << 1) | ++ ((led[2] > 0) << 2) | ((led[3] > 0) << 3) | ++ ((led[0] & 1) << 4) | ((led[1] & 1) << 5) | ++ ((led[2] & 1) << 6) | ((led[3] & 1) << 7); /* Tested OK */ ++ b4xxp_setreg8(b4, R_GPIO_EN1, leds & 0x0f); ++ b4xxp_setreg8(b4, R_GPIO_OUT1, leds >> 4); ++ } ++ ++ else if (b4->card_type == QUADBRI) { ++ leds = ((led[0] > 0) << 0) | ((led[1] > 0) << 1) | ++ ((led[2] > 0) << 2) | ((led[3] > 0) << 3) | ++ ((led[0] & 1) << 4) | ((led[1] & 1) << 5) | ++ ((led[2] & 1) << 6) | ((led[3] & 1) << 7); /* UNTESTED */ ++ b4xxp_setreg8(b4, R_GPIO_EN1, leds & 0x0f); ++ b4xxp_setreg8(b4, R_GPIO_OUT1, leds >> 4); ++ } ++ ++ else if (b4->card_type == BN4S0) { ++ leds = ((led[0] > 0) << 0) | ((led[1] > 0) << 1) | ++ ((led[2] > 0) << 2) | ((led[3] > 0) << 3) | ++ ((led[0] & 1) << 4) | ((led[1] & 1) << 5) | ++ ((led[2] & 1) << 6) | ((led[3] & 1) << 7); /* UNTESTED */ ++ b4xxp_setreg8(b4, R_GPIO_EN1, leds & 0x0f); ++ b4xxp_setreg8(b4, R_GPIO_OUT1, leds >> 4); ++ } ++ ++ else if (b4->card_type == B200P_OV) { ++ leds = ((led[0] > 0) << 0) | ((led[1] > 0) << 1) | ++ ((led[0] & 1) << 4) | ((led[1] & 1) << 5); ++ b4xxp_setreg8(b4, R_GPIO_EN1, leds & 0x0f); ++ b4xxp_setreg8(b4, R_GPIO_OUT1, leds >> 4); /* Tested OK */ ++ } ++ ++ else if (b4->card_type == DUOBRI) { ++ leds = ((led[0] > 0) << 0) | ((led[1] > 0) << 1) | ++ ((led[0] & 1) << 4) | ((led[1] & 1) << 5); ++ b4xxp_setreg8(b4, R_GPIO_EN1, leds & 0x0f); ++ b4xxp_setreg8(b4, R_GPIO_OUT1, leds >> 4); /* UNTESTED */ ++ } ++ ++ else if (b4->card_type == BN2S0) { ++ leds = ((led[0] > 0) << 0) | ((led[1] > 0) << 1) | ++ ((led[0] & 1) << 4) | ((led[1] & 1) << 5); ++ b4xxp_setreg8(b4, R_GPIO_EN1, leds & 0x0f); ++ b4xxp_setreg8(b4, R_GPIO_OUT1, leds >> 4); /* UNTESTED */ ++ } ++ ++ 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 +2056,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 +2354,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 && b4->has_ec) + bspan->span.echocan = b4xxp_echocan; + + /* HDLC stuff */ +@@ -2245,13 +2461,24 @@ 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; ++ if ( b4->numspans == 8 ) /* HFC-4S d-chan fifos 8-11 *** HFC-8S d-chan fifos 16-23 */ ++ { ++ 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 +2487,7 @@ 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 +2496,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 +2505,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 +2513,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 +2595,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 +2606,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 +2615,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 +2710,8 @@ 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->has_ec = dt->has_ec; ++ b4->card_type = dt->card_type; + b4->pdev = pdev; + b4->dev = &pdev->dev; + pci_set_drvdata(pdev, b4); +@@ -2497,7 +2725,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 +2740,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 +2888,17 @@ 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 }, ++ {0, } ++ + }; + + static struct pci_driver b4xx_driver = { +@@ -2719,7 +2957,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 /usr/src/originales/dahdi-linux-2.1.0.4/drivers/dahdi/wcb4xxp/wcb4xxp.h /usr/src/dahdi-linux-2.1.0.4/drivers/dahdi/wcb4xxp/wcb4xxp.h +--- a/drivers/dahdi/wcb4xxp/wcb4xxp.h 2008-11-24 04:14:37.000000000 +0000 ++++ b/drivers/dahdi/wcb4xxp/wcb4xxp.h 2009-03-09 23:50:18.000000000 +0000 +@@ -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,19 @@ 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 */ ++ }; ++ + /* This structure exists one per card */ + struct b4xxp { + unsigned magic; /* magic value to make sure we're looking at our struct */ +@@ -448,10 +461,12 @@ struct b4xxp { + int globalconfig; /* Whether global setup has been done */ + int syncspan; /* span that HFC uses for sync on this card */ + int running; /* interrupts are enabled */ +- ++ + struct b4xxp_span spans[MAX_SPANS_PER_CARD]; /* Individual spans */ + int order; /* Order */ + int flags; /* Device flags */ ++ int has_ec; /* Has ECHO Cancel */ ++ enum cards_ids card_type; /* Card Identifier (using ids_cards enum)*/ + int master; /* Are we master */ + int ledreg; /* copy of the LED Register */ + unsigned int gpio; |