mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-05-11 09:48:24 +02:00
* Asterisk jetzt in der Version 1.2.7.1 mit Bristuff 0.3.0-PRE-1o und Florz-Patch git-svn-id: http://svn.ipfire.org/svn/ipfire/trunk@119 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8
1294 lines
42 KiB
Diff
1294 lines
42 KiB
Diff
diff -urN bristuff-0.3.0-PRE-1o/zaphfc/Makefile zaphfc_0.3.0-PRE-1o_florz-12/Makefile
|
|
--- bristuff-0.3.0-PRE-1o/zaphfc/Makefile 2006-02-09 10:11:05.000000000 +0100
|
|
+++ zaphfc_0.3.0-PRE-1o_florz-12/Makefile 2006-05-02 03:24:31.000000000 +0200
|
|
@@ -1,15 +1,15 @@
|
|
-KINCLUDES = /usr/src/linux/include
|
|
+KSRC=/usr/src/linux/
|
|
+KINCLUDES = $(KSRC)include
|
|
BRISTUFFBASE = $(shell dirname `pwd`)
|
|
|
|
ZAP = $(shell [ -f $(BRISTUFFBASE)/zaptel/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel")
|
|
-RTAI = $(shell [ -f /usr/realtime/include/rtai.h ] && echo "-DRTAITIMING -I/usr/realtime/include")
|
|
|
|
HOSTCC=gcc
|
|
|
|
-CFLAGS+=-I. $(ZAP) $(RTAI) -O2 -g -Wall -DBUILDING_TONEZONE
|
|
+CFLAGS+=-I. $(ZAP) -O2 -g -Wall -DBUILDING_TONEZONE
|
|
CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
|
|
|
|
-KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP) $(RTAI) -Wall
|
|
+KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP) -Wall
|
|
KFLAGS+=$(shell [ -f $(KINCLUDES)/linux/modversions.h ] && echo "-DMODVERSIONS -include $(KINCLUDES)/linux/modversions.h")
|
|
KFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-msoft-float -fsigned-char"; fi)
|
|
|
|
@@ -105,8 +105,8 @@
|
|
zaphfc.ko: zaphfc.c zaphfc.h
|
|
|
|
linux26:
|
|
- @if ! [ -d /usr/src/linux-2.6 ]; then echo "Link /usr/src/linux-2.6 to your kernel sources first!"; exit 1 ; fi
|
|
- make -C /usr/src/linux-2.6 SUBDIRS=$(PWD) ZAP=$(ZAP) modules
|
|
+ @if ! [ -d $(KSRC) ]; then echo "Link /usr/src/linux-2.6 to your kernel sources first!"; exit 1 ; fi
|
|
+ make -C $(KSRC) SUBDIRS=$(PWD) ZAP=$(ZAP) modules
|
|
|
|
install: install$(BUILDVER)
|
|
|
|
diff -urN bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.c zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.c
|
|
--- bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.c 2006-04-25 15:38:47.000000000 +0200
|
|
+++ zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.c 2006-05-02 03:24:31.000000000 +0200
|
|
@@ -7,19 +7,21 @@
|
|
*
|
|
* 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 Public License.
|
|
+ * distributed under the terms of the GNU General Public License.
|
|
*
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
-#ifdef RTAITIMING
|
|
-#include <asm/io.h>
|
|
-#include <rtai.h>
|
|
-#include <rtai_sched.h>
|
|
-#include <rtai_fifos.h>
|
|
-#endif
|
|
#include <linux/pci.h>
|
|
#include <linux/init.h>
|
|
#include <linux/interrupt.h>
|
|
@@ -27,6 +29,8 @@
|
|
#include <zaptel.h>
|
|
#include "zaphfc.h"
|
|
|
|
+#define log2(n) ffz(~(n))
|
|
+
|
|
#if CONFIG_PCI
|
|
|
|
#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */
|
|
@@ -69,41 +73,30 @@
|
|
static int hfc_dev_count = 0;
|
|
static int modes = 0; // all TE
|
|
static int debug = 0;
|
|
+static int sync_slave = 0; // all master
|
|
+static int timer_card = 0;
|
|
+static int jitterbuffer = 1;
|
|
static struct pci_dev *multi_hfc = NULL;
|
|
static spinlock_t registerlock = SPIN_LOCK_UNLOCKED;
|
|
|
|
-void hfc_shutdownCard(struct hfc_card *hfctmp) {
|
|
- unsigned long flags;
|
|
-
|
|
- if (hfctmp == NULL) {
|
|
- return;
|
|
- }
|
|
-
|
|
- if (hfctmp->pci_io == NULL) {
|
|
- return;
|
|
- }
|
|
-
|
|
- spin_lock_irqsave(&hfctmp->lock,flags);
|
|
-
|
|
+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);
|
|
|
|
- /* Reset pending interrupts */
|
|
- hfc_inb(hfctmp, hfc_INT_S1);
|
|
+ /* Remove interrupt handler */
|
|
+ free_irq(hfctmp->irq,hfctmp);
|
|
+}
|
|
+
|
|
+void hfc_shutdownCard2(struct hfc_card *hfctmp) {
|
|
+ unsigned long flags;
|
|
|
|
- /* Wait for interrupts that might still be pending */
|
|
- 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);
|
|
|
|
- /* Remove interrupt handler */
|
|
- if (hfctmp->irq) {
|
|
- free_irq(hfctmp->irq, hfctmp);
|
|
- }
|
|
+ /* Reset pending interrupts */
|
|
+ hfc_inb(hfctmp, hfc_INT_S1);
|
|
|
|
/* Soft-reset the card */
|
|
hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET); // softreset on
|
|
@@ -117,8 +110,8 @@
|
|
|
|
pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, 0); // disable memio and bustmaster
|
|
|
|
- if (hfctmp->fifomem != NULL) {
|
|
- kfree(hfctmp->fifomem);
|
|
+ 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;
|
|
@@ -128,11 +121,24 @@
|
|
spin_unlock_irqrestore(&hfctmp->lock,flags);
|
|
if (hfctmp->ztdev != NULL) {
|
|
zt_unregister(&hfctmp->ztdev->span);
|
|
- kfree(hfctmp->ztdev);
|
|
+ vfree(hfctmp->ztdev);
|
|
printk(KERN_INFO "unregistered from zaptel.\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;
|
|
|
|
@@ -176,14 +182,14 @@
|
|
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 = 0;
|
|
+ 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);
|
|
-
|
|
-#ifdef RTAITIMING
|
|
- hfctmp->regs.int_m2 = 0;
|
|
-#else
|
|
- hfctmp->regs.int_m2 = hfc_M2_PROC_TRANS;
|
|
-#endif
|
|
hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
|
|
|
|
/* Clear already pending ints */
|
|
@@ -195,8 +201,8 @@
|
|
hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_TE; /* set tx_lo mode, error in datasheet ! */
|
|
}
|
|
|
|
- hfctmp->regs.mst_mode = hfc_MST_MODE_MASTER; /* HFC Master Mode */
|
|
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;
|
|
@@ -208,10 +214,8 @@
|
|
hfc_outb(hfctmp, hfc_CIRM, 0x80 | 0x40); // bit order
|
|
|
|
/* Finally enable IRQ output */
|
|
-#ifndef RTAITIMING
|
|
hfctmp->regs.int_m2 |= hfc_M2_IRQ_ENABLE;
|
|
hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
|
|
-#endif
|
|
|
|
/* clear pending ints */
|
|
hfc_inb(hfctmp, hfc_INT_S1);
|
|
@@ -228,374 +232,219 @@
|
|
spin_unlock(®isterlock);
|
|
}
|
|
|
|
-static void hfc_btrans(struct hfc_card *hfctmp, char whichB) {
|
|
- // we are called with irqs disabled from the irq handler
|
|
- int count, maxlen, total;
|
|
- unsigned char *f1, *f2;
|
|
- unsigned short *z1, *z2, newz1;
|
|
- int freebytes;
|
|
-
|
|
- if (whichB == 1) {
|
|
- f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F1);
|
|
- f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F2);
|
|
- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z1 + (*f1 * 4));
|
|
- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z2 + (*f1 * 4));
|
|
- } else {
|
|
- f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F1);
|
|
- f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F2);
|
|
- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z1 + (*f1 * 4));
|
|
- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z2 + (*f1 * 4));
|
|
- }
|
|
-
|
|
- freebytes = *z2 - *z1;
|
|
- if (freebytes <= 0) {
|
|
- freebytes += hfc_B_FIFO_SIZE;
|
|
- }
|
|
- count = ZT_CHUNKSIZE;
|
|
-
|
|
- total = count;
|
|
- if (freebytes < count) {
|
|
- hfctmp->clicks++;
|
|
- /* only spit out this warning once per second to not make things worse! */
|
|
- if (hfctmp->clicks > 100) {
|
|
- printk(KERN_CRIT "zaphfc: bchan tx fifo full, dropping audio! (z1=%d, z2=%d)\n",*z1,*z2);
|
|
- hfctmp->clicks = 0;
|
|
- }
|
|
- return;
|
|
- }
|
|
-
|
|
- maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z1;
|
|
- if (maxlen > count) {
|
|
- maxlen = count;
|
|
- }
|
|
- newz1 = *z1 + total;
|
|
- if (newz1 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { newz1 -= hfc_B_FIFO_SIZE; }
|
|
+/*===========================================================================*/
|
|
|
|
- if (whichB == 1) {
|
|
- memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + *z1),hfctmp->ztdev->chans[0].writechunk, maxlen);
|
|
- } else {
|
|
- memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + *z1),hfctmp->ztdev->chans[1].writechunk, maxlen);
|
|
- }
|
|
-
|
|
- count -= maxlen;
|
|
- if (count > 0) {
|
|
- // Buffer wrap
|
|
- if (whichB == 1) {
|
|
- memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[0].writechunk+maxlen, count);
|
|
- } else {
|
|
- memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[1].writechunk+maxlen, count);
|
|
- }
|
|
- }
|
|
+#if hfc_B_FIFO_SIZE%ZT_CHUNKSIZE
|
|
+#error hfc_B_FIFO_SIZE is not a multiple of ZT_CHUNKSIZE even though the code assumes this
|
|
+#endif
|
|
+
|
|
+static void hfc_dch_init(struct hfc_card *hfctmp){
|
|
+ struct dch *chtmp=&hfctmp->dch;
|
|
|
|
- *z1 = newz1; /* send it now */
|
|
+ chtmp->rx.f1.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DRX_F1);
|
|
+ chtmp->rx.f2.v=0x1f;
|
|
+ chtmp->rx.f2.z2.v=0x1ff;
|
|
|
|
-// if (count > 0) printk(KERN_CRIT "zaphfc: bchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2);
|
|
- return;
|
|
+ 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_brec(struct hfc_card *hfctmp, char whichB) {
|
|
- // we are called with irqs disabled from the irq handler
|
|
- int count, maxlen, drop;
|
|
- volatile unsigned char *f1, *f2;
|
|
- volatile unsigned short *z1, *z2, newz2;
|
|
- int bytes = 0;
|
|
-
|
|
- if (whichB == 1) {
|
|
- f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F1);
|
|
- f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F2);
|
|
- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z1 + (*f1 * 4));
|
|
- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4));
|
|
- } else {
|
|
- f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F1);
|
|
- f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F2);
|
|
- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z1 + (*f1 * 4));
|
|
- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4));
|
|
- }
|
|
+static void hfc_bch_init(struct hfc_card *hfctmp){
|
|
+ struct bch *chtmp=&hfctmp->bch;
|
|
|
|
- bytes = *z1 - *z2;
|
|
- if (bytes < 0) {
|
|
- bytes += hfc_B_FIFO_SIZE;
|
|
- }
|
|
- count = ZT_CHUNKSIZE;
|
|
-
|
|
- if (bytes < ZT_CHUNKSIZE) {
|
|
-#ifndef RTAITIMING
|
|
- printk(KERN_CRIT "zaphfc: bchan rx fifo not enough bytes to receive! (z1=%d, z2=%d, wanted %d got %d), probably a buffer overrun.\n",*z1,*z2,ZT_CHUNKSIZE,bytes);
|
|
-#endif
|
|
- return;
|
|
- }
|
|
+ chtmp->checkcnt=0;
|
|
+ chtmp->fill_fifo=0;
|
|
|
|
- /* allowing the buffering of hfc_BCHAN_BUFFER bytes of audio data works around irq jitter */
|
|
- if (bytes > hfc_BCHAN_BUFFER + ZT_CHUNKSIZE) {
|
|
- /* if the system is too slow to handle it, we will have to drop it all (except 1 zaptel chunk) */
|
|
- drop = bytes - ZT_CHUNKSIZE;
|
|
- hfctmp->clicks++;
|
|
- /* only spit out this warning once per second to not make things worse! */
|
|
- if (hfctmp->clicks > 100) {
|
|
- printk(KERN_CRIT "zaphfc: dropped audio (z1=%d, z2=%d, wanted %d got %d, dropped %d).\n",*z1,*z2,count,bytes,drop);
|
|
- hfctmp->clicks = 0;
|
|
- }
|
|
- /* hm, we are processing the b chan data tooooo slowly... let's drop the lost audio */
|
|
- newz2 = *z2 + drop;
|
|
- if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) {
|
|
- newz2 -= hfc_B_FIFO_SIZE;
|
|
- }
|
|
- *z2 = newz2;
|
|
- }
|
|
+ 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;
|
|
|
|
-
|
|
- maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z2;
|
|
- if (maxlen > count) {
|
|
- maxlen = count;
|
|
- }
|
|
- if (whichB == 1) {
|
|
- memcpy(hfctmp->ztdev->chans[0].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + *z2), maxlen);
|
|
- } else {
|
|
- memcpy(hfctmp->ztdev->chans[1].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + *z2), maxlen);
|
|
- }
|
|
- newz2 = *z2 + count;
|
|
- if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) {
|
|
- newz2 -= hfc_B_FIFO_SIZE;
|
|
+ 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;
|
|
}
|
|
- *z2 = newz2;
|
|
-
|
|
- count -= maxlen;
|
|
- if (count > 0) {
|
|
- // Buffer wrap
|
|
- if (whichB == 1) {
|
|
- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4));
|
|
- memcpy(hfctmp->ztdev->chans[0].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + hfc_B_SUB_VAL), count);
|
|
- } else {
|
|
- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4));
|
|
- memcpy(hfctmp->ztdev->chans[1].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + hfc_B_SUB_VAL), count);
|
|
- }
|
|
- newz2 = *z2 + count;
|
|
- if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) {
|
|
- newz2 -= hfc_B_FIFO_SIZE;
|
|
+ if(chtmp->fill_fifo){
|
|
+ chtmp->checkcnt++;
|
|
+ chtmp->checkcnt%=ZT_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<=ZT_CHUNKSIZE*jitterbuffer&&chtmp->tx.c[1].filled<=ZT_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
|
|
|
|
- if (whichB == 1) {
|
|
- zt_ec_chunk(&hfctmp->ztdev->chans[0], hfctmp->ztdev->chans[0].readchunk, hfctmp->ztdev->chans[0].writechunk);
|
|
- } else {
|
|
- zt_ec_chunk(&hfctmp->ztdev->chans[1], hfctmp->ztdev->chans[1].readchunk, hfctmp->ztdev->chans[1].writechunk);
|
|
+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,ZT_CHUNKSIZE);
|
|
+ hfc_bch_inc_z(chtmp->tx.z1,ZT_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);
|
|
}
|
|
- return;
|
|
+ if(!chtmp->fill_fifo)
|
|
+ for(x=0;x<2;x++)*chtmp->tx.c[x].z1p=chtmp->tx.z1;
|
|
}
|
|
|
|
-
|
|
-static void hfc_dtrans(struct hfc_card *hfctmp) {
|
|
- // we are called with irqs disabled from the irq handler
|
|
+static void hfc_bch_rx(struct hfc_card *hfctmp){
|
|
+ struct bch *chtmp=&hfctmp->bch;
|
|
int x;
|
|
- int count, maxlen, total;
|
|
- unsigned char *f1, *f2, newf1;
|
|
- unsigned short *z1, *z2, newz1;
|
|
- int frames, freebytes;
|
|
|
|
- if (hfctmp->ztdev->chans[2].bytes2transmit == 0) {
|
|
- return;
|
|
+ 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;
|
|
}
|
|
-
|
|
- f1 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F1);
|
|
- f2 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F2);
|
|
- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4));
|
|
- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z2 + (*f1 * 4));
|
|
-
|
|
- frames = (*f1 - *f2) & hfc_FMASK;
|
|
- if (frames < 0) {
|
|
- frames += hfc_MAX_DFRAMES + 1;
|
|
+ if(chtmp->rx.c[0].filled>=ZT_CHUNKSIZE&&chtmp->rx.c[1].filled>=ZT_CHUNKSIZE){
|
|
+ if((chtmp->rx.c[0].filled>=ZT_CHUNKSIZE*(jitterbuffer+2)&&chtmp->rx.c[1].filled>=ZT_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%ZT_CHUNKSIZE-ZT_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),ZT_CHUNKSIZE);
|
|
+ zt_ec_chunk(&hfctmp->ztdev->chans[x],hfctmp->ztdev->chans[x].readchunk,hfctmp->ztdev->chans[x].writechunk);
|
|
+ }
|
|
+ hfc_bch_inc_z(chtmp->rx.z2,ZT_CHUNKSIZE);
|
|
}
|
|
+}
|
|
|
|
- if (frames >= hfc_MAX_DFRAMES) {
|
|
- printk(KERN_CRIT "zaphfc: dchan tx fifo total number of frames exceeded!\n");
|
|
- return;
|
|
- }
|
|
+/*===========================================================================*/
|
|
|
|
- freebytes = *z2 - *z1;
|
|
- if (freebytes <= 0) {
|
|
- freebytes += hfc_D_FIFO_SIZE;
|
|
- }
|
|
- count = hfctmp->ztdev->chans[2].bytes2transmit;
|
|
-
|
|
- total = count;
|
|
- if (freebytes < count) {
|
|
- printk(KERN_CRIT "zaphfc: dchan tx fifo not enough free bytes! (z1=%d, z2=%d)\n",*z1,*z2);
|
|
- return;
|
|
- }
|
|
-
|
|
- newz1 = (*z1 + count) & hfc_ZMASK;
|
|
- newf1 = ((*f1 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1); // next frame
|
|
-
|
|
- if (count > 0) {
|
|
- if (debug) {
|
|
- printk(KERN_CRIT "zaphfc: card %d TX [ ", hfctmp->cardno);
|
|
- for (x=0; x<count; x++) {
|
|
+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]);
|
|
}
|
|
- if (hfctmp->ztdev->chans[2].eoftx == 1) {
|
|
- printk("] %d bytes\n", count);
|
|
- } else {
|
|
- printk("..] %d bytes\n", count);
|
|
- }
|
|
- }
|
|
- maxlen = hfc_D_FIFO_SIZE - *z1;
|
|
- if (maxlen > count) {
|
|
- maxlen = count;
|
|
+ printk("] %d bytes\n",hfctmp->ztdev->chans[2].bytes2transmit);
|
|
}
|
|
- memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF + *z1),hfctmp->ztdev->chans[2].writechunk, maxlen);
|
|
- count -= maxlen;
|
|
- if (count > 0) {
|
|
- memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF),(char *)(hfctmp->ztdev->chans[2].writechunk + maxlen), count);
|
|
+ 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;
|
|
+ }
|
|
}
|
|
}
|
|
-
|
|
- *z1 = newz1;
|
|
-
|
|
- if (hfctmp->ztdev->chans[2].eoftx == 1) {
|
|
- *f1 = newf1;
|
|
- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4));
|
|
- *z1 = newz1;
|
|
- hfctmp->ztdev->chans[2].eoftx = 0;
|
|
- }
|
|
-// printk(KERN_CRIT "zaphfc: dchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2);
|
|
- return;
|
|
}
|
|
|
|
-/* receive a complete hdlc frame, skip broken or short frames */
|
|
-static void hfc_drec(struct hfc_card *hfctmp) {
|
|
- int count=0, maxlen=0, framelen=0;
|
|
- unsigned char *f1, *f2, *crcstat;
|
|
- unsigned short *z1, *z2, oldz2, newz2;
|
|
+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;
|
|
-
|
|
- /* put the received data into the zaptel buffer
|
|
- we'll call zt_receive() later when the timer fires. */
|
|
- f1 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F1);
|
|
- f2 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F2);
|
|
-
|
|
- if (*f1 == *f2) return; /* nothing received, strange eh? */
|
|
-
|
|
- z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z1 + (*f2 * 4));
|
|
- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
|
|
-
|
|
- /* calculate length of frame, including 2 bytes CRC and 1 byte STAT */
|
|
- count = *z1 - *z2;
|
|
-
|
|
- if (count < 0) {
|
|
- count += hfc_D_FIFO_SIZE; /* ring buffer wrapped */
|
|
- }
|
|
- count++;
|
|
- framelen = count;
|
|
-
|
|
- crcstat = (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z1);
|
|
-
|
|
- if ((framelen < 4) || (*crcstat != 0x0)) {
|
|
- /* the frame is too short for a valid HDLC frame or the CRC is borked */
|
|
- printk(KERN_CRIT "zaphfc: empty HDLC frame or bad CRC received (framelen = %d, stat = %#x, card = %d).\n", framelen, *crcstat, hfctmp->cardno);
|
|
- oldz2 = *z2;
|
|
- *f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1); /* NEXT!!! */
|
|
- // recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!!
|
|
- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
|
|
- *z2 = (oldz2 + framelen) & hfc_ZMASK;
|
|
- hfctmp->drecinframe = 0;
|
|
- hfctmp->regs.int_drec--;
|
|
- /* skip short or broken frames */
|
|
- hfctmp->ztdev->chans[2].bytes2receive = 0;
|
|
- return;
|
|
- }
|
|
-
|
|
- count -= 1; /* strip STAT */
|
|
- hfctmp->ztdev->chans[2].eofrx = 1;
|
|
-
|
|
- if (count + *z2 <= hfc_D_FIFO_SIZE) {
|
|
- maxlen = count;
|
|
- } else {
|
|
- maxlen = hfc_D_FIFO_SIZE - *z2;
|
|
+ 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);
|
|
}
|
|
-
|
|
- /* copy first part */
|
|
- memcpy(hfctmp->drecbuf, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z2), maxlen);
|
|
- hfctmp->ztdev->chans[2].bytes2receive += maxlen;
|
|
-
|
|
- count -= maxlen;
|
|
- if (count > 0) {
|
|
- /* ring buffer wrapped, copy rest from start of d fifo */
|
|
- memcpy(hfctmp->drecbuf + maxlen, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF), count);
|
|
- hfctmp->ztdev->chans[2].bytes2receive += count;
|
|
- }
|
|
-
|
|
- /* frame read */
|
|
- oldz2 = *z2;
|
|
- newz2 = (oldz2 + framelen) & hfc_ZMASK;
|
|
- *f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1); /* NEXT!!! */
|
|
- /* recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!! */
|
|
- z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
|
|
- *z2 = newz2;
|
|
- hfctmp->drecinframe = 0;
|
|
- hfctmp->regs.int_drec--;
|
|
}
|
|
|
|
-#ifndef RTAITIMING
|
|
+/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
|
|
+
|
|
#ifdef LINUX26
|
|
static irqreturn_t hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
|
|
#else
|
|
static void hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
|
|
#endif
|
|
struct hfc_card *hfctmp = dev_id;
|
|
- unsigned long flags = 0;
|
|
- unsigned char stat;
|
|
-#else
|
|
-static void hfc_service(struct hfc_card *hfctmp) {
|
|
-#endif
|
|
+ struct hfc_card *hfctmp2;
|
|
struct zt_hfc *zthfc;
|
|
- unsigned char s1, s2, l1state;
|
|
+ unsigned char stat, s1, s2, l1state;
|
|
+ unsigned long flags;
|
|
+ unsigned long flags2=0;
|
|
int x;
|
|
|
|
if (!hfctmp) {
|
|
-#ifndef RTAITIMING
|
|
#ifdef LINUX26
|
|
return IRQ_NONE;
|
|
#else
|
|
return;
|
|
#endif
|
|
-#else
|
|
- /* rtai */
|
|
- return;
|
|
-#endif
|
|
}
|
|
|
|
if (!hfctmp->pci_io) {
|
|
printk(KERN_WARNING "%s: IO-mem disabled, cannot handle interrupt\n",
|
|
__FUNCTION__);
|
|
-#ifndef RTAITIMING
|
|
#ifdef LINUX26
|
|
return IRQ_NONE;
|
|
#else
|
|
return;
|
|
#endif
|
|
-#else
|
|
- /* rtai */
|
|
- return;
|
|
-#endif
|
|
}
|
|
-
|
|
- /* we assume a few things in this irq handler:
|
|
- - the hfc-pci will only generate "timer" irqs (proc/non-proc)
|
|
- - we need to use every 8th IRQ (to generate 1khz timing)
|
|
- OR
|
|
- - if we use rtai for timing the hfc-pci will not generate ANY irq,
|
|
- instead rtai will call this "fake" irq with a 1khz realtime timer. :)
|
|
- - rtai will directly service the card, not like it used to by triggering
|
|
- the linux irq
|
|
- */
|
|
|
|
-#ifndef RTAITIMING
|
|
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);
|
|
@@ -605,8 +454,6 @@
|
|
return;
|
|
#endif
|
|
}
|
|
-#endif
|
|
-
|
|
s1 = hfc_inb(hfctmp, hfc_INT_S1);
|
|
s2 = hfc_inb(hfctmp, hfc_INT_S2);
|
|
if (s1 != 0) {
|
|
@@ -625,18 +472,10 @@
|
|
}
|
|
switch (l1state) {
|
|
case 3:
|
|
-#ifdef RTAITIMING
|
|
- sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state);
|
|
-#else
|
|
sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d)", hfctmp->cardno, l1state);
|
|
-#endif
|
|
break;
|
|
default:
|
|
-#ifdef RTAITIMING
|
|
- sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state);
|
|
-#else
|
|
sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d)", hfctmp->cardno, l1state);
|
|
-#endif
|
|
}
|
|
if (l1state == 2) {
|
|
hfc_outb(hfctmp, hfc_STATES, hfc_STATES_ACTIVATE | hfc_STATES_DO_ACTION | hfc_STATES_NT_G2_G3);
|
|
@@ -650,18 +489,10 @@
|
|
}
|
|
switch (l1state) {
|
|
case 7:
|
|
-#ifdef RTAITIMING
|
|
- sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state);
|
|
-#else
|
|
sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d)", hfctmp->cardno, l1state);
|
|
-#endif
|
|
break;
|
|
default:
|
|
-#ifdef RTAITIMING
|
|
- sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state);
|
|
-#else
|
|
sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d)", hfctmp->cardno, l1state);
|
|
-#endif
|
|
}
|
|
if (l1state == 3) {
|
|
hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
|
|
@@ -671,7 +502,7 @@
|
|
}
|
|
if (s1 & hfc_INTS_DREC) {
|
|
// D chan RX (bit 5)
|
|
- hfctmp->regs.int_drec++;
|
|
+ hfctmp->regs.int_drec = 1;
|
|
// mr. zapata there is something for you!
|
|
// printk(KERN_CRIT "d chan rx\n");
|
|
}
|
|
@@ -692,14 +523,10 @@
|
|
// B1 chan TX (bit 0)
|
|
}
|
|
}
|
|
-#ifdef RTAITIMING
|
|
- /* fake an irq */
|
|
- s2 |= hfc_M2_PROC_TRANS;
|
|
-#endif
|
|
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");
|
|
+ // 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)
|
|
@@ -707,32 +534,30 @@
|
|
if (s2 & hfc_M2_GCI_I_CHG) {
|
|
// GCI I-change (bit 1)
|
|
}
|
|
- if (s2 & hfc_M2_PROC_TRANS) {
|
|
+ if((s2&hfc_M2_PROC_TRANS)&&(hfctmp->cardno==timer_card)){
|
|
// processing/non-processing transition (bit 0)
|
|
- hfctmp->ticks++;
|
|
-#ifndef RTAITIMING
|
|
- if (hfctmp->ticks > 7) {
|
|
- // welcome to zaptel timing :)
|
|
-#endif
|
|
- hfctmp->ticks = 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 & ZT_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;
|
|
|
|
zt_transmit(&(hfctmp->ztdev->span));
|
|
|
|
- hfc_btrans(hfctmp,1);
|
|
- hfc_btrans(hfctmp,2);
|
|
- hfc_dtrans(hfctmp);
|
|
+ hfc_bch_tx(hfctmp);
|
|
+ hfc_dch_tx(hfctmp);
|
|
}
|
|
-
|
|
- hfc_brec(hfctmp,1);
|
|
- hfc_brec(hfctmp,2);
|
|
- if (hfctmp->regs.int_drec > 0) {
|
|
+ hfc_bch_rx(hfctmp);
|
|
+ if (hfctmp->regs.int_drec) {
|
|
// dchan data to read
|
|
- hfc_drec(hfctmp);
|
|
+ hfc_dch_rx(hfctmp);
|
|
if (hfctmp->ztdev->chans[2].bytes2receive > 0) {
|
|
if (debug) {
|
|
printk(KERN_CRIT "zaphfc: card %d RX [ ", hfctmp->cardno);
|
|
@@ -757,19 +582,18 @@
|
|
if (hfctmp->ztdev->span.flags & ZT_FLAG_RUNNING) {
|
|
zt_receive(&(hfctmp->ztdev->span));
|
|
}
|
|
-
|
|
-#ifndef RTAITIMING
|
|
}
|
|
-#endif
|
|
+ if(hfctmp!=hfctmp2)spin_unlock_irqrestore(&hfctmp->lock,flags2);
|
|
+ }
|
|
+ hfctmp=hfctmp->next;
|
|
+ }
|
|
+ hfctmp=hfctmp2;
|
|
}
|
|
-
|
|
}
|
|
-#ifndef RTAITIMING
|
|
spin_unlock_irqrestore(&hfctmp->lock,flags);
|
|
#ifdef LINUX26
|
|
return IRQ_RETVAL(1);
|
|
#endif
|
|
-#endif
|
|
}
|
|
|
|
|
|
@@ -826,22 +650,21 @@
|
|
}
|
|
alreadyrunning = span->flags & ZT_FLAG_RUNNING;
|
|
|
|
- if (!alreadyrunning) {
|
|
- span->chans[2].flags &= ~ZT_FLAG_HDLC;
|
|
- span->chans[2].flags |= ZT_FLAG_BRIDCHAN;
|
|
-
|
|
- span->flags |= ZT_FLAG_RUNNING;
|
|
+ if (alreadyrunning) return 0;
|
|
|
|
- hfctmp->ticks = -2;
|
|
- hfctmp->clicks = 0;
|
|
- hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
|
|
- hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
|
|
- } else {
|
|
- return 0;
|
|
- }
|
|
+ span->chans[2].flags &= ~ZT_FLAG_HDLC;
|
|
+ span->chans[2].flags |= ZT_FLAG_BRIDCHAN;
|
|
+
|
|
+ span->flags |= ZT_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;
|
|
}
|
|
|
|
@@ -871,17 +694,9 @@
|
|
|
|
sprintf(zthfc->span.name, "ZTHFC%d", hfc_dev_count + 1);
|
|
if (hfctmp->regs.nt_mode == 1) {
|
|
-#ifdef RTAITIMING
|
|
- sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] [realtime]", hfc_dev_count + 1);
|
|
-#else
|
|
sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT]", hfc_dev_count + 1);
|
|
-#endif
|
|
} else {
|
|
-#ifdef RTAITIMING
|
|
- sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] [realtime]", hfc_dev_count + 1);
|
|
-#else
|
|
sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE]", hfc_dev_count + 1);
|
|
-#endif
|
|
}
|
|
|
|
zthfc->span.spanconfig = zthfc_spanconfig;
|
|
@@ -918,32 +733,6 @@
|
|
return 0;
|
|
}
|
|
|
|
-#ifdef RTAITIMING
|
|
-#define TICK_PERIOD 1000000
|
|
-#define TICK_PERIOD2 1000000000
|
|
-#define TASK_PRIORITY 1
|
|
-#define STACK_SIZE 10000
|
|
-
|
|
-static RT_TASK rt_task;
|
|
-static struct hfc_card *rtai_hfc_list[hfc_MAX_CARDS];
|
|
-static unsigned char rtai_hfc_counter = 0;
|
|
-
|
|
-static void rtai_register_hfc(struct hfc_card *hfctmp) {
|
|
- rtai_hfc_list[rtai_hfc_counter++] = hfctmp;
|
|
-}
|
|
-
|
|
-static void rtai_loop(int t) {
|
|
- int i=0;
|
|
- for (;;) {
|
|
- for (i=0; i < rtai_hfc_counter; i++) {
|
|
- if (rtai_hfc_list[i] != NULL)
|
|
- hfc_service(rtai_hfc_list[i]);
|
|
- }
|
|
- rt_task_wait_period();
|
|
- }
|
|
-}
|
|
-#endif
|
|
-
|
|
int hfc_findCards(int pcivendor, int pcidevice, char *vendor_name, char *card_name) {
|
|
struct pci_dev *tmp;
|
|
struct hfc_card *hfctmp = NULL;
|
|
@@ -959,9 +748,9 @@
|
|
}
|
|
pci_set_master(tmp);
|
|
|
|
- hfctmp = kmalloc(sizeof(struct hfc_card), GFP_KERNEL);
|
|
+ hfctmp = vmalloc(sizeof(struct hfc_card));
|
|
if (!hfctmp) {
|
|
- printk(KERN_WARNING "zaphfc: unable to kmalloc!\n");
|
|
+ printk(KERN_WARNING "zaphfc: unable to vmalloc!\n");
|
|
pci_disable_device(tmp);
|
|
multi_hfc = NULL;
|
|
return -ENOMEM;
|
|
@@ -969,6 +758,7 @@
|
|
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;
|
|
@@ -982,49 +772,39 @@
|
|
hfctmp->pci_io = (char *) tmp->resource[1].start;
|
|
if (!hfctmp->pci_io) {
|
|
printk(KERN_WARNING "zaphfc: no iomem!\n");
|
|
- kfree(hfctmp);
|
|
+ vfree(hfctmp);
|
|
pci_disable_device(tmp);
|
|
multi_hfc = NULL;
|
|
return -1;
|
|
}
|
|
-
|
|
- hfctmp->fifomem = kmalloc(65536, GFP_KERNEL);
|
|
- if (!hfctmp->fifomem) {
|
|
- printk(KERN_WARNING "zaphfc: unable to kmalloc fifomem!\n");
|
|
- kfree(hfctmp);
|
|
+
|
|
+ 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 {
|
|
- memset(hfctmp->fifomem, 0x0, 65536);
|
|
- hfctmp->fifos = (void *)(((ulong) hfctmp->fifomem) & ~0x7FFF) + 0x8000;
|
|
pci_write_config_dword(hfctmp->pcidev, 0x80, (u_int) virt_to_bus(hfctmp->fifos));
|
|
hfctmp->pci_io = ioremap((ulong) hfctmp->pci_io, 256);
|
|
}
|
|
|
|
-#ifdef RTAITIMING
|
|
- /* we need no stinking irq */
|
|
- hfctmp->irq = 0;
|
|
-#else
|
|
if (request_irq(hfctmp->irq, &hfc_interrupt, SA_INTERRUPT | SA_SHIRQ, "zaphfc", hfctmp)) {
|
|
printk(KERN_WARNING "zaphfc: unable to register irq\n");
|
|
- kfree(hfctmp->fifomem);
|
|
- kfree(hfctmp);
|
|
+ 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;
|
|
}
|
|
-#endif
|
|
|
|
-#ifdef RTAITIMING
|
|
- rtai_register_hfc(hfctmp);
|
|
-#endif
|
|
printk(KERN_INFO
|
|
- "zaphfc: %s %s configured at mem %lx fifo %lx(%#x) IRQ %d HZ %d\n",
|
|
+ "zaphfc: %s %s configured at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n",
|
|
vendor_name, card_name,
|
|
- (unsigned long) hfctmp->pci_io,
|
|
- (unsigned long) hfctmp->fifos,
|
|
+ (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
|
|
@@ -1041,11 +821,21 @@
|
|
hfctmp->regs.nt_mode = 0;
|
|
}
|
|
|
|
- zthfc = kmalloc(sizeof(struct zt_hfc),GFP_KERNEL);
|
|
+ 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 zt_hfc));
|
|
if (!zthfc) {
|
|
- printk(KERN_CRIT "zaphfc: unable to kmalloc!\n");
|
|
+ printk(KERN_CRIT "zaphfc: unable to vmalloc!\n");
|
|
hfc_shutdownCard(hfctmp);
|
|
- kfree(hfctmp);
|
|
+ vfree(hfctmp);
|
|
multi_hfc = NULL;
|
|
return -ENOMEM;
|
|
}
|
|
@@ -1071,7 +861,6 @@
|
|
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_find_device(pcivendor, pcidevice, multi_hfc);
|
|
@@ -1079,58 +868,42 @@
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
-
|
|
int init_module(void) {
|
|
int i = 0;
|
|
-#ifdef RTAITIMING
|
|
- RTIME tick_period;
|
|
- for (i=0; i < hfc_MAX_CARDS; i++) {
|
|
- rtai_hfc_list[i] = NULL;
|
|
+ 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;
|
|
}
|
|
- rt_set_periodic_mode();
|
|
-#endif
|
|
- i = 0;
|
|
+ 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++;
|
|
}
|
|
-#ifdef RTAITIMING
|
|
- for (i=0; i < hfc_MAX_CARDS; i++) {
|
|
- if (rtai_hfc_list[i]) {
|
|
- printk(KERN_INFO
|
|
- "zaphfc: configured %d at mem %#x fifo %#x(%#x) for realtime servicing\n",
|
|
- rtai_hfc_list[i]->cardno,
|
|
- (u_int) rtai_hfc_list[i]->pci_io,
|
|
- (u_int) rtai_hfc_list[i]->fifos,
|
|
- (u_int) virt_to_bus(rtai_hfc_list[i]->fifos));
|
|
-
|
|
- }
|
|
- }
|
|
- rt_task_init(&rt_task, rtai_loop, 1, STACK_SIZE, TASK_PRIORITY, 0, 0);
|
|
- tick_period = start_rt_timer(nano2count(TICK_PERIOD));
|
|
- rt_task_make_periodic(&rt_task, rt_get_time() + tick_period, tick_period);
|
|
-#endif
|
|
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;
|
|
-#ifdef RTAITIMING
|
|
- stop_rt_timer();
|
|
- rt_task_delete(&rt_task);
|
|
-#endif
|
|
+
|
|
printk(KERN_INFO "zaphfc: stop\n");
|
|
// spin_lock(®isterlock);
|
|
+ tmpcard=hfc_dev_list;
|
|
+ while(tmpcard){
|
|
+ hfc_shutdownCard1(tmpcard);
|
|
+ tmpcard=tmpcard->next;
|
|
+ }
|
|
while (hfc_dev_list != NULL) {
|
|
if (hfc_dev_list == NULL) break;
|
|
- hfc_shutdownCard(hfc_dev_list);
|
|
+ hfc_shutdownCard2(hfc_dev_list);
|
|
tmpcard = hfc_dev_list;
|
|
hfc_dev_list = hfc_dev_list->next;
|
|
if (tmpcard != NULL) {
|
|
- kfree(tmpcard);
|
|
+ vfree(tmpcard);
|
|
tmpcard = NULL;
|
|
printk(KERN_INFO "zaphfc: freed one card.\n");
|
|
}
|
|
@@ -1141,11 +914,17 @@
|
|
|
|
|
|
#ifdef LINUX26
|
|
-module_param(modes, int, 0600);
|
|
+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);
|
|
#else
|
|
MODULE_PARM(modes,"i");
|
|
MODULE_PARM(debug,"i");
|
|
+MODULE_PARM(sync_slave,"i");
|
|
+MODULE_PARM(timer_card,"i");
|
|
+MODULE_PARM(jitterbuffer,"i");
|
|
#endif
|
|
|
|
MODULE_DESCRIPTION("HFC-S PCI A Zaptel Driver");
|
|
@@ -1153,3 +932,6 @@
|
|
#ifdef MODULE_LICENSE
|
|
MODULE_LICENSE("GPL");
|
|
#endif
|
|
+
|
|
+/* vim:set sw=4: */
|
|
+
|
|
diff -urN bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.h zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.h
|
|
--- bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.h 2005-02-26 23:30:32.000000000 +0100
|
|
+++ zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.h 2005-03-02 20:43:04.000000000 +0100
|
|
@@ -135,8 +135,12 @@
|
|
/* 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
|
|
@@ -236,6 +240,9 @@
|
|
#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 {
|
|
@@ -249,20 +256,67 @@
|
|
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;
|
|
- int clicks;
|
|
unsigned char *pci_io;
|
|
- void *fifomem; // start of the shared mem
|
|
- volatile void *fifos; // 32k aligned mem for the fifos
|
|
+ void *fifos; // 32k aligned mem for the fifos
|
|
struct hfc_regs regs;
|
|
unsigned int pcibus;
|
|
unsigned int pcidevfn;
|
|
@@ -274,6 +328,9 @@
|
|
unsigned char brecbuf[2][ZT_CHUNKSIZE];
|
|
unsigned char btransbuf[2][ZT_CHUNKSIZE];
|
|
unsigned char cardno;
|
|
+ int active;
|
|
+ struct bch bch;
|
|
+ struct dch dch;
|
|
struct hfc_card *next;
|
|
} hfc_card;
|
|
|
|
@@ -284,6 +341,5 @@
|
|
struct hfc_card *card;
|
|
} zt_hfc;
|
|
|
|
-/* tune this */
|
|
-#define hfc_BCHAN_BUFFER 8
|
|
-#define hfc_MAX_CARDS 8
|
|
+/* vim:set sw=4: */
|
|
+
|