]>
Commit | Line | Data |
---|---|---|
5f892677 MT |
1 | diff -urN bristuff-0.3.0-PRE-1o/zaphfc/Makefile zaphfc_0.3.0-PRE-1o_florz-12/Makefile |
2 | --- bristuff-0.3.0-PRE-1o/zaphfc/Makefile 2006-02-09 10:11:05.000000000 +0100 | |
3 | +++ zaphfc_0.3.0-PRE-1o_florz-12/Makefile 2006-05-02 03:24:31.000000000 +0200 | |
4 | @@ -1,15 +1,15 @@ | |
5 | -KINCLUDES = /usr/src/linux/include | |
6 | +KSRC=/usr/src/linux/ | |
7 | +KINCLUDES = $(KSRC)include | |
8 | BRISTUFFBASE = $(shell dirname `pwd`) | |
9 | ||
10 | ZAP = $(shell [ -f $(BRISTUFFBASE)/zaptel/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel") | |
11 | -RTAI = $(shell [ -f /usr/realtime/include/rtai.h ] && echo "-DRTAITIMING -I/usr/realtime/include") | |
12 | ||
13 | HOSTCC=gcc | |
14 | ||
15 | -CFLAGS+=-I. $(ZAP) $(RTAI) -O2 -g -Wall -DBUILDING_TONEZONE | |
16 | +CFLAGS+=-I. $(ZAP) -O2 -g -Wall -DBUILDING_TONEZONE | |
17 | CFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi) | |
18 | ||
19 | -KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP) $(RTAI) -Wall | |
20 | +KFLAGS=-D__KERNEL__ -DMODULE -DEXPORT_SYMTAB -fomit-frame-pointer -O2 -Wall -I$(KINCLUDES) $(ZAP) -Wall | |
21 | KFLAGS+=$(shell [ -f $(KINCLUDES)/linux/modversions.h ] && echo "-DMODVERSIONS -include $(KINCLUDES)/linux/modversions.h") | |
22 | KFLAGS+=$(shell if uname -m | grep -q ppc; then echo "-msoft-float -fsigned-char"; fi) | |
23 | ||
24 | @@ -105,8 +105,8 @@ | |
25 | zaphfc.ko: zaphfc.c zaphfc.h | |
26 | ||
27 | linux26: | |
28 | - @if ! [ -d /usr/src/linux-2.6 ]; then echo "Link /usr/src/linux-2.6 to your kernel sources first!"; exit 1 ; fi | |
29 | - make -C /usr/src/linux-2.6 SUBDIRS=$(PWD) ZAP=$(ZAP) modules | |
30 | + @if ! [ -d $(KSRC) ]; then echo "Link /usr/src/linux-2.6 to your kernel sources first!"; exit 1 ; fi | |
31 | + make -C $(KSRC) SUBDIRS=$(PWD) ZAP=$(ZAP) modules | |
32 | ||
33 | install: install$(BUILDVER) | |
34 | ||
35 | diff -urN bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.c zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.c | |
36 | --- bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.c 2006-04-25 15:38:47.000000000 +0200 | |
37 | +++ zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.c 2006-05-02 03:24:31.000000000 +0200 | |
38 | @@ -7,19 +7,21 @@ | |
39 | * | |
40 | * Klaus-Peter Junghanns <kpj@junghanns.net> | |
41 | * | |
42 | + * Copyright (C) 2004, 2005, 2006 Florian Zumbiehl <florz@gmx.de> | |
43 | + * - support for slave mode of the HFC-S chip which allows it to | |
44 | + * sync its sample clock to an external source/another HFC chip | |
45 | + * - support for "interrupt bundling" (let only one card generate | |
46 | + * 8 kHz timing interrupt no matter how many cards there are | |
47 | + * in the system) | |
48 | + * - interrupt loss tolerant b channel handling | |
49 | + * | |
50 | * This program is free software and may be modified and | |
51 | - * distributed under the terms of the GNU Public License. | |
52 | + * distributed under the terms of the GNU General Public License. | |
53 | * | |
54 | */ | |
55 | ||
56 | #include <linux/kernel.h> | |
57 | #include <linux/module.h> | |
58 | -#ifdef RTAITIMING | |
59 | -#include <asm/io.h> | |
60 | -#include <rtai.h> | |
61 | -#include <rtai_sched.h> | |
62 | -#include <rtai_fifos.h> | |
63 | -#endif | |
64 | #include <linux/pci.h> | |
65 | #include <linux/init.h> | |
66 | #include <linux/interrupt.h> | |
67 | @@ -27,6 +29,8 @@ | |
68 | #include <zaptel.h> | |
69 | #include "zaphfc.h" | |
70 | ||
71 | +#define log2(n) ffz(~(n)) | |
72 | + | |
73 | #if CONFIG_PCI | |
74 | ||
75 | #define CLKDEL_TE 0x0f /* CLKDEL in TE mode */ | |
76 | @@ -69,41 +73,30 @@ | |
77 | static int hfc_dev_count = 0; | |
78 | static int modes = 0; // all TE | |
79 | static int debug = 0; | |
80 | +static int sync_slave = 0; // all master | |
81 | +static int timer_card = 0; | |
82 | +static int jitterbuffer = 1; | |
83 | static struct pci_dev *multi_hfc = NULL; | |
84 | static spinlock_t registerlock = SPIN_LOCK_UNLOCKED; | |
85 | ||
86 | -void hfc_shutdownCard(struct hfc_card *hfctmp) { | |
87 | - unsigned long flags; | |
88 | - | |
89 | - if (hfctmp == NULL) { | |
90 | - return; | |
91 | - } | |
92 | - | |
93 | - if (hfctmp->pci_io == NULL) { | |
94 | - return; | |
95 | - } | |
96 | - | |
97 | - spin_lock_irqsave(&hfctmp->lock,flags); | |
98 | - | |
99 | +void hfc_shutdownCard1(struct hfc_card *hfctmp) { | |
100 | printk(KERN_INFO "zaphfc: shutting down card at %p.\n",hfctmp->pci_io); | |
101 | ||
102 | /* Clear interrupt mask */ | |
103 | hfctmp->regs.int_m2 = 0; | |
104 | hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2); | |
105 | ||
106 | - /* Reset pending interrupts */ | |
107 | - hfc_inb(hfctmp, hfc_INT_S1); | |
108 | + /* Remove interrupt handler */ | |
109 | + free_irq(hfctmp->irq,hfctmp); | |
110 | +} | |
111 | + | |
112 | +void hfc_shutdownCard2(struct hfc_card *hfctmp) { | |
113 | + unsigned long flags; | |
114 | ||
115 | - /* Wait for interrupts that might still be pending */ | |
116 | - spin_unlock_irqrestore(&hfctmp->lock, flags); | |
117 | - set_current_state(TASK_UNINTERRUPTIBLE); | |
118 | - schedule_timeout((30 * HZ) / 1000); // wait 30 ms | |
119 | spin_lock_irqsave(&hfctmp->lock,flags); | |
120 | ||
121 | - /* Remove interrupt handler */ | |
122 | - if (hfctmp->irq) { | |
123 | - free_irq(hfctmp->irq, hfctmp); | |
124 | - } | |
125 | + /* Reset pending interrupts */ | |
126 | + hfc_inb(hfctmp, hfc_INT_S1); | |
127 | ||
128 | /* Soft-reset the card */ | |
129 | hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET); // softreset on | |
130 | @@ -117,8 +110,8 @@ | |
131 | ||
132 | pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, 0); // disable memio and bustmaster | |
133 | ||
134 | - if (hfctmp->fifomem != NULL) { | |
135 | - kfree(hfctmp->fifomem); | |
136 | + if (hfctmp->fifos != NULL) { | |
137 | + free_pages((unsigned long)hfctmp->fifos,log2(hfc_FIFO_MEM_SIZE_PAGES)); | |
138 | } | |
139 | iounmap((void *) hfctmp->pci_io); | |
140 | hfctmp->pci_io = NULL; | |
141 | @@ -128,11 +121,24 @@ | |
142 | spin_unlock_irqrestore(&hfctmp->lock,flags); | |
143 | if (hfctmp->ztdev != NULL) { | |
144 | zt_unregister(&hfctmp->ztdev->span); | |
145 | - kfree(hfctmp->ztdev); | |
146 | + vfree(hfctmp->ztdev); | |
147 | printk(KERN_INFO "unregistered from zaptel.\n"); | |
148 | } | |
149 | } | |
150 | ||
151 | +void hfc_shutdownCard(struct hfc_card *hfctmp) { | |
152 | + if (hfctmp == NULL) { | |
153 | + return; | |
154 | + } | |
155 | + | |
156 | + if (hfctmp->pci_io == NULL) { | |
157 | + return; | |
158 | + } | |
159 | + | |
160 | + hfc_shutdownCard1(hfctmp); | |
161 | + hfc_shutdownCard2(hfctmp); | |
162 | +} | |
163 | + | |
164 | void hfc_resetCard(struct hfc_card *hfctmp) { | |
165 | unsigned long flags; | |
166 | ||
167 | @@ -176,14 +182,14 @@ | |
168 | hfctmp->regs.ctmt = hfc_CTMT_TRANSB1 | hfc_CTMT_TRANSB2; // all bchans are transparent , no freaking hdlc | |
169 | hfc_outb(hfctmp, hfc_CTMT, hfctmp->regs.ctmt); | |
170 | ||
171 | - hfctmp->regs.int_m1 = 0; | |
172 | + hfctmp->regs.int_m1=hfc_INTS_L1STATE; | |
173 | + if(hfctmp->cardno==timer_card){ | |
174 | + hfctmp->regs.int_m2=hfc_M2_PROC_TRANS; | |
175 | + }else{ | |
176 | + hfctmp->regs.int_m1|=hfc_INTS_DREC; | |
177 | + hfctmp->regs.int_m2=0; | |
178 | + } | |
179 | hfc_outb(hfctmp, hfc_INT_M1, hfctmp->regs.int_m1); | |
180 | - | |
181 | -#ifdef RTAITIMING | |
182 | - hfctmp->regs.int_m2 = 0; | |
183 | -#else | |
184 | - hfctmp->regs.int_m2 = hfc_M2_PROC_TRANS; | |
185 | -#endif | |
186 | hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2); | |
187 | ||
188 | /* Clear already pending ints */ | |
189 | @@ -195,8 +201,8 @@ | |
190 | hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_TE; /* set tx_lo mode, error in datasheet ! */ | |
191 | } | |
192 | ||
193 | - hfctmp->regs.mst_mode = hfc_MST_MODE_MASTER; /* HFC Master Mode */ | |
194 | hfc_outb(hfctmp, hfc_MST_MODE, hfctmp->regs.mst_mode); | |
195 | + hfc_outb(hfctmp, hfc_MST_EMOD, hfctmp->regs.mst_emod); | |
196 | ||
197 | hfc_outb(hfctmp, hfc_SCTRL, hfctmp->regs.sctrl); | |
198 | hfctmp->regs.sctrl_r = 3; | |
199 | @@ -208,10 +214,8 @@ | |
200 | hfc_outb(hfctmp, hfc_CIRM, 0x80 | 0x40); // bit order | |
201 | ||
202 | /* Finally enable IRQ output */ | |
203 | -#ifndef RTAITIMING | |
204 | hfctmp->regs.int_m2 |= hfc_M2_IRQ_ENABLE; | |
205 | hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2); | |
206 | -#endif | |
207 | ||
208 | /* clear pending ints */ | |
209 | hfc_inb(hfctmp, hfc_INT_S1); | |
210 | @@ -228,374 +232,219 @@ | |
211 | spin_unlock(®isterlock); | |
212 | } | |
213 | ||
214 | -static void hfc_btrans(struct hfc_card *hfctmp, char whichB) { | |
215 | - // we are called with irqs disabled from the irq handler | |
216 | - int count, maxlen, total; | |
217 | - unsigned char *f1, *f2; | |
218 | - unsigned short *z1, *z2, newz1; | |
219 | - int freebytes; | |
220 | - | |
221 | - if (whichB == 1) { | |
222 | - f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F1); | |
223 | - f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F2); | |
224 | - z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z1 + (*f1 * 4)); | |
225 | - z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z2 + (*f1 * 4)); | |
226 | - } else { | |
227 | - f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F1); | |
228 | - f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F2); | |
229 | - z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z1 + (*f1 * 4)); | |
230 | - z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z2 + (*f1 * 4)); | |
231 | - } | |
232 | - | |
233 | - freebytes = *z2 - *z1; | |
234 | - if (freebytes <= 0) { | |
235 | - freebytes += hfc_B_FIFO_SIZE; | |
236 | - } | |
237 | - count = ZT_CHUNKSIZE; | |
238 | - | |
239 | - total = count; | |
240 | - if (freebytes < count) { | |
241 | - hfctmp->clicks++; | |
242 | - /* only spit out this warning once per second to not make things worse! */ | |
243 | - if (hfctmp->clicks > 100) { | |
244 | - printk(KERN_CRIT "zaphfc: bchan tx fifo full, dropping audio! (z1=%d, z2=%d)\n",*z1,*z2); | |
245 | - hfctmp->clicks = 0; | |
246 | - } | |
247 | - return; | |
248 | - } | |
249 | - | |
250 | - maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z1; | |
251 | - if (maxlen > count) { | |
252 | - maxlen = count; | |
253 | - } | |
254 | - newz1 = *z1 + total; | |
255 | - if (newz1 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { newz1 -= hfc_B_FIFO_SIZE; } | |
256 | +/*===========================================================================*/ | |
257 | ||
258 | - if (whichB == 1) { | |
259 | - memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + *z1),hfctmp->ztdev->chans[0].writechunk, maxlen); | |
260 | - } else { | |
261 | - memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + *z1),hfctmp->ztdev->chans[1].writechunk, maxlen); | |
262 | - } | |
263 | - | |
264 | - count -= maxlen; | |
265 | - if (count > 0) { | |
266 | - // Buffer wrap | |
267 | - if (whichB == 1) { | |
268 | - memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[0].writechunk+maxlen, count); | |
269 | - } else { | |
270 | - memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[1].writechunk+maxlen, count); | |
271 | - } | |
272 | - } | |
273 | +#if hfc_B_FIFO_SIZE%ZT_CHUNKSIZE | |
274 | +#error hfc_B_FIFO_SIZE is not a multiple of ZT_CHUNKSIZE even though the code assumes this | |
275 | +#endif | |
276 | + | |
277 | +static void hfc_dch_init(struct hfc_card *hfctmp){ | |
278 | + struct dch *chtmp=&hfctmp->dch; | |
279 | ||
280 | - *z1 = newz1; /* send it now */ | |
281 | + chtmp->rx.f1.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DRX_F1); | |
282 | + chtmp->rx.f2.v=0x1f; | |
283 | + chtmp->rx.f2.z2.v=0x1ff; | |
284 | ||
285 | -// 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); | |
286 | - return; | |
287 | + chtmp->tx.f1.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DTX_F1); | |
288 | + chtmp->tx.f1.v=0x1f; | |
289 | + chtmp->tx.f1.z1.v=0x1ff; | |
290 | + chtmp->tx.f2.p=(u8 *)(hfctmp->fifos+hfc_FIFO_DTX_F2); | |
291 | } | |
292 | ||
293 | -static void hfc_brec(struct hfc_card *hfctmp, char whichB) { | |
294 | - // we are called with irqs disabled from the irq handler | |
295 | - int count, maxlen, drop; | |
296 | - volatile unsigned char *f1, *f2; | |
297 | - volatile unsigned short *z1, *z2, newz2; | |
298 | - int bytes = 0; | |
299 | - | |
300 | - if (whichB == 1) { | |
301 | - f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F1); | |
302 | - f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F2); | |
303 | - z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z1 + (*f1 * 4)); | |
304 | - z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4)); | |
305 | - } else { | |
306 | - f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F1); | |
307 | - f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F2); | |
308 | - z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z1 + (*f1 * 4)); | |
309 | - z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4)); | |
310 | - } | |
311 | +static void hfc_bch_init(struct hfc_card *hfctmp){ | |
312 | + struct bch *chtmp=&hfctmp->bch; | |
313 | ||
314 | - bytes = *z1 - *z2; | |
315 | - if (bytes < 0) { | |
316 | - bytes += hfc_B_FIFO_SIZE; | |
317 | - } | |
318 | - count = ZT_CHUNKSIZE; | |
319 | - | |
320 | - if (bytes < ZT_CHUNKSIZE) { | |
321 | -#ifndef RTAITIMING | |
322 | - 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); | |
323 | -#endif | |
324 | - return; | |
325 | - } | |
326 | + chtmp->checkcnt=0; | |
327 | + chtmp->fill_fifo=0; | |
328 | ||
329 | - /* allowing the buffering of hfc_BCHAN_BUFFER bytes of audio data works around irq jitter */ | |
330 | - if (bytes > hfc_BCHAN_BUFFER + ZT_CHUNKSIZE) { | |
331 | - /* if the system is too slow to handle it, we will have to drop it all (except 1 zaptel chunk) */ | |
332 | - drop = bytes - ZT_CHUNKSIZE; | |
333 | - hfctmp->clicks++; | |
334 | - /* only spit out this warning once per second to not make things worse! */ | |
335 | - if (hfctmp->clicks > 100) { | |
336 | - printk(KERN_CRIT "zaphfc: dropped audio (z1=%d, z2=%d, wanted %d got %d, dropped %d).\n",*z1,*z2,count,bytes,drop); | |
337 | - hfctmp->clicks = 0; | |
338 | - } | |
339 | - /* hm, we are processing the b chan data tooooo slowly... let's drop the lost audio */ | |
340 | - newz2 = *z2 + drop; | |
341 | - if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { | |
342 | - newz2 -= hfc_B_FIFO_SIZE; | |
343 | - } | |
344 | - *z2 = newz2; | |
345 | - } | |
346 | + chtmp->rx.c[0].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1RX_Z1+0x1f*4); | |
347 | + chtmp->rx.c[0].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B1RX_ZOFF); | |
348 | + chtmp->rx.c[1].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2RX_Z1+0x1f*4); | |
349 | + chtmp->rx.c[1].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B2RX_ZOFF); | |
350 | + chtmp->rx.z2=hfc_B_SUB_VAL; | |
351 | + chtmp->rx.diff=0; | |
352 | ||
353 | - | |
354 | - maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z2; | |
355 | - if (maxlen > count) { | |
356 | - maxlen = count; | |
357 | - } | |
358 | - if (whichB == 1) { | |
359 | - memcpy(hfctmp->ztdev->chans[0].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + *z2), maxlen); | |
360 | - } else { | |
361 | - memcpy(hfctmp->ztdev->chans[1].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + *z2), maxlen); | |
362 | - } | |
363 | - newz2 = *z2 + count; | |
364 | - if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { | |
365 | - newz2 -= hfc_B_FIFO_SIZE; | |
366 | + chtmp->tx.c[0].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1TX_Z1+0x1f*4); | |
367 | + chtmp->tx.c[0].z2p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B1TX_Z2+0x1f*4); | |
368 | + chtmp->tx.c[0].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B1TX_ZOFF); | |
369 | + chtmp->tx.c[0].filled=0; | |
370 | + chtmp->tx.c[1].z1p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2TX_Z1+0x1f*4); | |
371 | + chtmp->tx.c[1].z2p=(unsigned short *)(hfctmp->fifos+hfc_FIFO_B2TX_Z2+0x1f*4); | |
372 | + chtmp->tx.c[1].fifo_base=(char *)(hfctmp->fifos+hfc_FIFO_B2TX_ZOFF); | |
373 | + chtmp->tx.c[1].filled=0; | |
374 | + chtmp->tx.z1=hfc_B_SUB_VAL; | |
375 | + chtmp->tx.diff=0; | |
376 | + | |
377 | + hfc_dch_init(hfctmp); | |
378 | + | |
379 | + chtmp->initialized=0; | |
380 | +} | |
381 | + | |
382 | +static int hfc_bch_check(struct hfc_card *hfctmp){ | |
383 | + struct bch *chtmp=&hfctmp->bch; | |
384 | + int x,r; | |
385 | + | |
386 | + for(x=0;x<2;x++){ | |
387 | + chtmp->tx.c[x].filled=(chtmp->tx.z1-*chtmp->tx.c[x].z2p+hfc_B_FIFO_SIZE)%hfc_B_FIFO_SIZE; | |
388 | + chtmp->rx.c[x].filled=(*chtmp->rx.c[x].z1p-chtmp->rx.z2+hfc_B_FIFO_SIZE)%hfc_B_FIFO_SIZE; | |
389 | } | |
390 | - *z2 = newz2; | |
391 | - | |
392 | - count -= maxlen; | |
393 | - if (count > 0) { | |
394 | - // Buffer wrap | |
395 | - if (whichB == 1) { | |
396 | - z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4)); | |
397 | - memcpy(hfctmp->ztdev->chans[0].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + hfc_B_SUB_VAL), count); | |
398 | - } else { | |
399 | - z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4)); | |
400 | - memcpy(hfctmp->ztdev->chans[1].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + hfc_B_SUB_VAL), count); | |
401 | - } | |
402 | - newz2 = *z2 + count; | |
403 | - if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { | |
404 | - newz2 -= hfc_B_FIFO_SIZE; | |
405 | + if(chtmp->fill_fifo){ | |
406 | + chtmp->checkcnt++; | |
407 | + chtmp->checkcnt%=ZT_CHUNKSIZE; | |
408 | + r=!chtmp->checkcnt; | |
409 | + }else{ | |
410 | + x=chtmp->tx.c[0].filled-chtmp->tx.c[1].filled; | |
411 | + if(abs(x-chtmp->tx.diff)>1){ | |
412 | + printk(KERN_CRIT "zaphfc[%d]: tx sync changed: %d, %d\n",hfctmp->cardno,chtmp->tx.c[0].filled,chtmp->tx.c[1].filled); | |
413 | + chtmp->tx.diff=x; | |
414 | } | |
415 | + r=chtmp->tx.c[0].filled<=ZT_CHUNKSIZE*jitterbuffer&&chtmp->tx.c[1].filled<=ZT_CHUNKSIZE*jitterbuffer; | |
416 | } | |
417 | + return(r); | |
418 | +} | |
419 | ||
420 | +#define hfc_bch_inc_z(a,b) (a)=((a)-hfc_B_SUB_VAL+(b))%hfc_B_FIFO_SIZE+hfc_B_SUB_VAL | |
421 | ||
422 | - if (whichB == 1) { | |
423 | - zt_ec_chunk(&hfctmp->ztdev->chans[0], hfctmp->ztdev->chans[0].readchunk, hfctmp->ztdev->chans[0].writechunk); | |
424 | - } else { | |
425 | - zt_ec_chunk(&hfctmp->ztdev->chans[1], hfctmp->ztdev->chans[1].readchunk, hfctmp->ztdev->chans[1].writechunk); | |
426 | +static void hfc_bch_tx(struct hfc_card *hfctmp){ | |
427 | + struct bch *chtmp=&hfctmp->bch; | |
428 | + int x; | |
429 | + | |
430 | + for(x=0;x<2;x++) | |
431 | + memcpy((void *)(chtmp->tx.c[x].fifo_base+chtmp->tx.z1),hfctmp->ztdev->chans[x].writechunk,ZT_CHUNKSIZE); | |
432 | + hfc_bch_inc_z(chtmp->tx.z1,ZT_CHUNKSIZE); | |
433 | + if(chtmp->fill_fifo){ | |
434 | + chtmp->fill_fifo--; | |
435 | + }else if(chtmp->tx.c[0].filled<=1||chtmp->tx.c[1].filled<=1){ | |
436 | + chtmp->fill_fifo=jitterbuffer; | |
437 | + if(chtmp->initialized) | |
438 | + printk(KERN_CRIT "zaphfc[%d]: b channel buffer underrun: %d, %d\n",hfctmp->cardno,chtmp->tx.c[0].filled,chtmp->tx.c[1].filled); | |
439 | } | |
440 | - return; | |
441 | + if(!chtmp->fill_fifo) | |
442 | + for(x=0;x<2;x++)*chtmp->tx.c[x].z1p=chtmp->tx.z1; | |
443 | } | |
444 | ||
445 | - | |
446 | -static void hfc_dtrans(struct hfc_card *hfctmp) { | |
447 | - // we are called with irqs disabled from the irq handler | |
448 | +static void hfc_bch_rx(struct hfc_card *hfctmp){ | |
449 | + struct bch *chtmp=&hfctmp->bch; | |
450 | int x; | |
451 | - int count, maxlen, total; | |
452 | - unsigned char *f1, *f2, newf1; | |
453 | - unsigned short *z1, *z2, newz1; | |
454 | - int frames, freebytes; | |
455 | ||
456 | - if (hfctmp->ztdev->chans[2].bytes2transmit == 0) { | |
457 | - return; | |
458 | + x=chtmp->rx.c[0].filled-chtmp->rx.c[1].filled; | |
459 | + if(abs(x-chtmp->rx.diff)>1){ | |
460 | + printk(KERN_CRIT "zaphfc[%d]: rx sync changed: %d, %d\n",hfctmp->cardno,chtmp->rx.c[0].filled,chtmp->rx.c[1].filled); | |
461 | + chtmp->rx.diff=x; | |
462 | } | |
463 | - | |
464 | - f1 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F1); | |
465 | - f2 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F2); | |
466 | - z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4)); | |
467 | - z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z2 + (*f1 * 4)); | |
468 | - | |
469 | - frames = (*f1 - *f2) & hfc_FMASK; | |
470 | - if (frames < 0) { | |
471 | - frames += hfc_MAX_DFRAMES + 1; | |
472 | + if(chtmp->rx.c[0].filled>=ZT_CHUNKSIZE&&chtmp->rx.c[1].filled>=ZT_CHUNKSIZE){ | |
473 | + if((chtmp->rx.c[0].filled>=ZT_CHUNKSIZE*(jitterbuffer+2)&&chtmp->rx.c[1].filled>=ZT_CHUNKSIZE*(jitterbuffer+2))||!chtmp->initialized){ | |
474 | + if(chtmp->initialized) | |
475 | + printk(KERN_CRIT "zaphfc[%d]: b channel buffer overflow: %d, %d\n",hfctmp->cardno,chtmp->rx.c[0].filled,chtmp->rx.c[1].filled); | |
476 | + hfc_bch_inc_z(chtmp->rx.z2,chtmp->rx.c[0].filled-chtmp->rx.c[0].filled%ZT_CHUNKSIZE-ZT_CHUNKSIZE); | |
477 | + chtmp->initialized=1; | |
478 | + } | |
479 | + for(x=0;x<2;x++){ | |
480 | + memcpy(hfctmp->ztdev->chans[x].readchunk,(void *)(chtmp->rx.c[x].fifo_base+chtmp->rx.z2),ZT_CHUNKSIZE); | |
481 | + zt_ec_chunk(&hfctmp->ztdev->chans[x],hfctmp->ztdev->chans[x].readchunk,hfctmp->ztdev->chans[x].writechunk); | |
482 | + } | |
483 | + hfc_bch_inc_z(chtmp->rx.z2,ZT_CHUNKSIZE); | |
484 | } | |
485 | +} | |
486 | ||
487 | - if (frames >= hfc_MAX_DFRAMES) { | |
488 | - printk(KERN_CRIT "zaphfc: dchan tx fifo total number of frames exceeded!\n"); | |
489 | - return; | |
490 | - } | |
491 | +/*===========================================================================*/ | |
492 | ||
493 | - freebytes = *z2 - *z1; | |
494 | - if (freebytes <= 0) { | |
495 | - freebytes += hfc_D_FIFO_SIZE; | |
496 | - } | |
497 | - count = hfctmp->ztdev->chans[2].bytes2transmit; | |
498 | - | |
499 | - total = count; | |
500 | - if (freebytes < count) { | |
501 | - printk(KERN_CRIT "zaphfc: dchan tx fifo not enough free bytes! (z1=%d, z2=%d)\n",*z1,*z2); | |
502 | - return; | |
503 | - } | |
504 | - | |
505 | - newz1 = (*z1 + count) & hfc_ZMASK; | |
506 | - newf1 = ((*f1 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1); // next frame | |
507 | - | |
508 | - if (count > 0) { | |
509 | - if (debug) { | |
510 | - printk(KERN_CRIT "zaphfc: card %d TX [ ", hfctmp->cardno); | |
511 | - for (x=0; x<count; x++) { | |
512 | +static void hfc_dch_tx(struct hfc_card *hfctmp){ | |
513 | + struct dch *chtmp=&hfctmp->dch; | |
514 | + u8 tx_f2_v; | |
515 | + u16 x; | |
516 | + | |
517 | + if(hfctmp->ztdev->chans[2].bytes2transmit){ | |
518 | + if(debug){ | |
519 | + printk(KERN_CRIT "zaphfc[%d]: card TX [ ",hfctmp->cardno); | |
520 | + for(x=0;x<hfctmp->ztdev->chans[2].bytes2transmit;x++){ | |
521 | printk("%#2x ",hfctmp->dtransbuf[x]); | |
522 | } | |
523 | - if (hfctmp->ztdev->chans[2].eoftx == 1) { | |
524 | - printk("] %d bytes\n", count); | |
525 | - } else { | |
526 | - printk("..] %d bytes\n", count); | |
527 | - } | |
528 | - } | |
529 | - maxlen = hfc_D_FIFO_SIZE - *z1; | |
530 | - if (maxlen > count) { | |
531 | - maxlen = count; | |
532 | + printk("] %d bytes\n",hfctmp->ztdev->chans[2].bytes2transmit); | |
533 | } | |
534 | - memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF + *z1),hfctmp->ztdev->chans[2].writechunk, maxlen); | |
535 | - count -= maxlen; | |
536 | - if (count > 0) { | |
537 | - memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF),(char *)(hfctmp->ztdev->chans[2].writechunk + maxlen), count); | |
538 | + tx_f2_v=*chtmp->tx.f2.p; | |
539 | + if(!(tx_f2_v-chtmp->tx.f1.v+hfc_MAX_DFRAMES+1-1)&(hfc_MAX_DFRAMES+1-1)){ | |
540 | + printk(KERN_CRIT "zaphfc[%d]: dchan tx fifo total number of frames exceeded!\n",hfctmp->cardno); | |
541 | + }else{ | |
542 | + 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){ | |
543 | + printk(KERN_CRIT "zaphfc[%d]: dchan tx fifo not enough space for frame!\n",hfctmp->cardno); | |
544 | + }else{ | |
545 | + chtmp->tx.f1.v=((chtmp->tx.f1.v+1)&hfc_MAX_DFRAMES)|(hfc_MAX_DFRAMES+1); | |
546 | + x=min(hfctmp->ztdev->chans[2].bytes2transmit,hfc_D_FIFO_SIZE-chtmp->tx.f1.z1.v); | |
547 | + memcpy(hfctmp->fifos+hfc_FIFO_DTX_ZOFF+chtmp->tx.f1.z1.v,hfctmp->ztdev->chans[2].writechunk,x); | |
548 | + memcpy(hfctmp->fifos+hfc_FIFO_DTX_ZOFF,hfctmp->ztdev->chans[2].writechunk+x,hfctmp->ztdev->chans[2].bytes2transmit-x); | |
549 | + *(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z2+chtmp->tx.f1.v*4)=chtmp->tx.f1.z1.v; | |
550 | + chtmp->tx.f1.z1.v=(chtmp->tx.f1.z1.v+hfctmp->ztdev->chans[2].bytes2transmit+hfc_D_FIFO_SIZE)&(hfc_D_FIFO_SIZE-1); | |
551 | + *(volatile u16 *)(hfctmp->fifos+hfc_FIFO_DTX_Z1+chtmp->tx.f1.v*4)=chtmp->tx.f1.z1.v; | |
552 | + *chtmp->tx.f1.p=chtmp->tx.f1.v; | |
553 | + } | |
554 | } | |
555 | } | |
556 | - | |
557 | - *z1 = newz1; | |
558 | - | |
559 | - if (hfctmp->ztdev->chans[2].eoftx == 1) { | |
560 | - *f1 = newf1; | |
561 | - z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4)); | |
562 | - *z1 = newz1; | |
563 | - hfctmp->ztdev->chans[2].eoftx = 0; | |
564 | - } | |
565 | -// printk(KERN_CRIT "zaphfc: dchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2); | |
566 | - return; | |
567 | } | |
568 | ||
569 | -/* receive a complete hdlc frame, skip broken or short frames */ | |
570 | -static void hfc_drec(struct hfc_card *hfctmp) { | |
571 | - int count=0, maxlen=0, framelen=0; | |
572 | - unsigned char *f1, *f2, *crcstat; | |
573 | - unsigned short *z1, *z2, oldz2, newz2; | |
574 | +static void hfc_dch_rx(struct hfc_card *hfctmp){ | |
575 | + struct dch *chtmp=&hfctmp->dch; | |
576 | + u16 size; | |
577 | ||
578 | hfctmp->ztdev->chans[2].bytes2receive=0; | |
579 | - hfctmp->ztdev->chans[2].eofrx = 0; | |
580 | - | |
581 | - /* put the received data into the zaptel buffer | |
582 | - we'll call zt_receive() later when the timer fires. */ | |
583 | - f1 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F1); | |
584 | - f2 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F2); | |
585 | - | |
586 | - if (*f1 == *f2) return; /* nothing received, strange eh? */ | |
587 | - | |
588 | - z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z1 + (*f2 * 4)); | |
589 | - z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4)); | |
590 | - | |
591 | - /* calculate length of frame, including 2 bytes CRC and 1 byte STAT */ | |
592 | - count = *z1 - *z2; | |
593 | - | |
594 | - if (count < 0) { | |
595 | - count += hfc_D_FIFO_SIZE; /* ring buffer wrapped */ | |
596 | - } | |
597 | - count++; | |
598 | - framelen = count; | |
599 | - | |
600 | - crcstat = (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z1); | |
601 | - | |
602 | - if ((framelen < 4) || (*crcstat != 0x0)) { | |
603 | - /* the frame is too short for a valid HDLC frame or the CRC is borked */ | |
604 | - printk(KERN_CRIT "zaphfc: empty HDLC frame or bad CRC received (framelen = %d, stat = %#x, card = %d).\n", framelen, *crcstat, hfctmp->cardno); | |
605 | - oldz2 = *z2; | |
606 | - *f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1); /* NEXT!!! */ | |
607 | - // recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!! | |
608 | - z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4)); | |
609 | - *z2 = (oldz2 + framelen) & hfc_ZMASK; | |
610 | - hfctmp->drecinframe = 0; | |
611 | - hfctmp->regs.int_drec--; | |
612 | - /* skip short or broken frames */ | |
613 | - hfctmp->ztdev->chans[2].bytes2receive = 0; | |
614 | - return; | |
615 | - } | |
616 | - | |
617 | - count -= 1; /* strip STAT */ | |
618 | - hfctmp->ztdev->chans[2].eofrx = 1; | |
619 | - | |
620 | - if (count + *z2 <= hfc_D_FIFO_SIZE) { | |
621 | - maxlen = count; | |
622 | - } else { | |
623 | - maxlen = hfc_D_FIFO_SIZE - *z2; | |
624 | + hfctmp->ztdev->chans[2].eofrx=0; | |
625 | + if(*chtmp->rx.f1.p==chtmp->rx.f2.v){ | |
626 | + hfctmp->regs.int_drec=0; | |
627 | + }else{ | |
628 | + 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; | |
629 | + if(size<4){ | |
630 | + printk(KERN_CRIT "zaphfc[%d]: empty HDLC frame received.\n",hfctmp->cardno); | |
631 | + }else{ | |
632 | + u16 x=min(size,(u16)(hfc_D_FIFO_SIZE-chtmp->rx.f2.z2.v)); | |
633 | + memcpy(hfctmp->drecbuf,hfctmp->fifos+hfc_FIFO_DRX_ZOFF+chtmp->rx.f2.z2.v,x); | |
634 | + memcpy(hfctmp->drecbuf+x,hfctmp->fifos+hfc_FIFO_DRX_ZOFF,size-x); | |
635 | + if(hfctmp->drecbuf[size-1]){ | |
636 | + printk(KERN_CRIT "zaphfc[%d]: received d channel frame with bad CRC.\n",hfctmp->cardno); | |
637 | + }else{ | |
638 | + hfctmp->ztdev->chans[2].bytes2receive=size-1; | |
639 | + hfctmp->ztdev->chans[2].eofrx=1; | |
640 | + } | |
641 | + } | |
642 | + chtmp->rx.f2.z2.v=(chtmp->rx.f2.z2.v+size)&(hfc_D_FIFO_SIZE-1); | |
643 | + chtmp->rx.f2.v=((chtmp->rx.f2.v+1)&hfc_MAX_DFRAMES)|(hfc_MAX_DFRAMES+1); | |
644 | } | |
645 | - | |
646 | - /* copy first part */ | |
647 | - memcpy(hfctmp->drecbuf, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z2), maxlen); | |
648 | - hfctmp->ztdev->chans[2].bytes2receive += maxlen; | |
649 | - | |
650 | - count -= maxlen; | |
651 | - if (count > 0) { | |
652 | - /* ring buffer wrapped, copy rest from start of d fifo */ | |
653 | - memcpy(hfctmp->drecbuf + maxlen, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF), count); | |
654 | - hfctmp->ztdev->chans[2].bytes2receive += count; | |
655 | - } | |
656 | - | |
657 | - /* frame read */ | |
658 | - oldz2 = *z2; | |
659 | - newz2 = (oldz2 + framelen) & hfc_ZMASK; | |
660 | - *f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1); /* NEXT!!! */ | |
661 | - /* recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!! */ | |
662 | - z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4)); | |
663 | - *z2 = newz2; | |
664 | - hfctmp->drecinframe = 0; | |
665 | - hfctmp->regs.int_drec--; | |
666 | } | |
667 | ||
668 | -#ifndef RTAITIMING | |
669 | +/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ | |
670 | + | |
671 | #ifdef LINUX26 | |
672 | static irqreturn_t hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { | |
673 | #else | |
674 | static void hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { | |
675 | #endif | |
676 | struct hfc_card *hfctmp = dev_id; | |
677 | - unsigned long flags = 0; | |
678 | - unsigned char stat; | |
679 | -#else | |
680 | -static void hfc_service(struct hfc_card *hfctmp) { | |
681 | -#endif | |
682 | + struct hfc_card *hfctmp2; | |
683 | struct zt_hfc *zthfc; | |
684 | - unsigned char s1, s2, l1state; | |
685 | + unsigned char stat, s1, s2, l1state; | |
686 | + unsigned long flags; | |
687 | + unsigned long flags2=0; | |
688 | int x; | |
689 | ||
690 | if (!hfctmp) { | |
691 | -#ifndef RTAITIMING | |
692 | #ifdef LINUX26 | |
693 | return IRQ_NONE; | |
694 | #else | |
695 | return; | |
696 | #endif | |
697 | -#else | |
698 | - /* rtai */ | |
699 | - return; | |
700 | -#endif | |
701 | } | |
702 | ||
703 | if (!hfctmp->pci_io) { | |
704 | printk(KERN_WARNING "%s: IO-mem disabled, cannot handle interrupt\n", | |
705 | __FUNCTION__); | |
706 | -#ifndef RTAITIMING | |
707 | #ifdef LINUX26 | |
708 | return IRQ_NONE; | |
709 | #else | |
710 | return; | |
711 | #endif | |
712 | -#else | |
713 | - /* rtai */ | |
714 | - return; | |
715 | -#endif | |
716 | } | |
717 | - | |
718 | - /* we assume a few things in this irq handler: | |
719 | - - the hfc-pci will only generate "timer" irqs (proc/non-proc) | |
720 | - - we need to use every 8th IRQ (to generate 1khz timing) | |
721 | - OR | |
722 | - - if we use rtai for timing the hfc-pci will not generate ANY irq, | |
723 | - instead rtai will call this "fake" irq with a 1khz realtime timer. :) | |
724 | - - rtai will directly service the card, not like it used to by triggering | |
725 | - the linux irq | |
726 | - */ | |
727 | ||
728 | -#ifndef RTAITIMING | |
729 | spin_lock_irqsave(&hfctmp->lock, flags); | |
730 | stat = hfc_inb(hfctmp, hfc_STATUS); | |
731 | - | |
732 | if ((stat & hfc_STATUS_ANYINT) == 0) { | |
733 | // maybe we are sharing the irq | |
734 | spin_unlock_irqrestore(&hfctmp->lock,flags); | |
735 | @@ -605,8 +454,6 @@ | |
736 | return; | |
737 | #endif | |
738 | } | |
739 | -#endif | |
740 | - | |
741 | s1 = hfc_inb(hfctmp, hfc_INT_S1); | |
742 | s2 = hfc_inb(hfctmp, hfc_INT_S2); | |
743 | if (s1 != 0) { | |
744 | @@ -625,18 +472,10 @@ | |
745 | } | |
746 | switch (l1state) { | |
747 | case 3: | |
748 | -#ifdef RTAITIMING | |
749 | - sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state); | |
750 | -#else | |
751 | sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d)", hfctmp->cardno, l1state); | |
752 | -#endif | |
753 | break; | |
754 | default: | |
755 | -#ifdef RTAITIMING | |
756 | - sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state); | |
757 | -#else | |
758 | sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d)", hfctmp->cardno, l1state); | |
759 | -#endif | |
760 | } | |
761 | if (l1state == 2) { | |
762 | hfc_outb(hfctmp, hfc_STATES, hfc_STATES_ACTIVATE | hfc_STATES_DO_ACTION | hfc_STATES_NT_G2_G3); | |
763 | @@ -650,18 +489,10 @@ | |
764 | } | |
765 | switch (l1state) { | |
766 | case 7: | |
767 | -#ifdef RTAITIMING | |
768 | - sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state); | |
769 | -#else | |
770 | sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d)", hfctmp->cardno, l1state); | |
771 | -#endif | |
772 | break; | |
773 | default: | |
774 | -#ifdef RTAITIMING | |
775 | - sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state); | |
776 | -#else | |
777 | sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d)", hfctmp->cardno, l1state); | |
778 | -#endif | |
779 | } | |
780 | if (l1state == 3) { | |
781 | hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE); | |
782 | @@ -671,7 +502,7 @@ | |
783 | } | |
784 | if (s1 & hfc_INTS_DREC) { | |
785 | // D chan RX (bit 5) | |
786 | - hfctmp->regs.int_drec++; | |
787 | + hfctmp->regs.int_drec = 1; | |
788 | // mr. zapata there is something for you! | |
789 | // printk(KERN_CRIT "d chan rx\n"); | |
790 | } | |
791 | @@ -692,14 +523,10 @@ | |
792 | // B1 chan TX (bit 0) | |
793 | } | |
794 | } | |
795 | -#ifdef RTAITIMING | |
796 | - /* fake an irq */ | |
797 | - s2 |= hfc_M2_PROC_TRANS; | |
798 | -#endif | |
799 | if (s2 != 0) { | |
800 | if (s2 & hfc_M2_PMESEL) { | |
801 | // kaboom irq (bit 7) | |
802 | - printk(KERN_CRIT "zaphfc: sync lost, pci performance too low. you might have some cpu throtteling enabled.\n"); | |
803 | + // printk(KERN_CRIT "zaphfc: sync lost, pci performance too low. you might have some cpu throtteling enabled.\n"); | |
804 | } | |
805 | if (s2 & hfc_M2_GCI_MON_REC) { | |
806 | // RxR monitor channel (bit 2) | |
807 | @@ -707,32 +534,30 @@ | |
808 | if (s2 & hfc_M2_GCI_I_CHG) { | |
809 | // GCI I-change (bit 1) | |
810 | } | |
811 | - if (s2 & hfc_M2_PROC_TRANS) { | |
812 | + if((s2&hfc_M2_PROC_TRANS)&&(hfctmp->cardno==timer_card)){ | |
813 | // processing/non-processing transition (bit 0) | |
814 | - hfctmp->ticks++; | |
815 | -#ifndef RTAITIMING | |
816 | - if (hfctmp->ticks > 7) { | |
817 | - // welcome to zaptel timing :) | |
818 | -#endif | |
819 | - hfctmp->ticks = 0; | |
820 | - | |
821 | + hfctmp2=hfctmp; | |
822 | + hfctmp=hfc_dev_list; | |
823 | + while(hfctmp){ | |
824 | + if(hfctmp->active){ | |
825 | + if(hfctmp!=hfctmp2)spin_lock_irqsave(&hfctmp->lock, flags2); | |
826 | + if(hfc_bch_check(hfctmp)){ | |
827 | if (hfctmp->ztdev->span.flags & ZT_FLAG_RUNNING) { | |
828 | // clear dchan buffer | |
829 | + // memset(hfctmp->drecbuf, 0x0, sizeof(hfctmp->drecbuf)); | |
830 | + | |
831 | hfctmp->ztdev->chans[2].bytes2transmit = 0; | |
832 | hfctmp->ztdev->chans[2].maxbytes2transmit = hfc_D_FIFO_SIZE; | |
833 | ||
834 | zt_transmit(&(hfctmp->ztdev->span)); | |
835 | ||
836 | - hfc_btrans(hfctmp,1); | |
837 | - hfc_btrans(hfctmp,2); | |
838 | - hfc_dtrans(hfctmp); | |
839 | + hfc_bch_tx(hfctmp); | |
840 | + hfc_dch_tx(hfctmp); | |
841 | } | |
842 | - | |
843 | - hfc_brec(hfctmp,1); | |
844 | - hfc_brec(hfctmp,2); | |
845 | - if (hfctmp->regs.int_drec > 0) { | |
846 | + hfc_bch_rx(hfctmp); | |
847 | + if (hfctmp->regs.int_drec) { | |
848 | // dchan data to read | |
849 | - hfc_drec(hfctmp); | |
850 | + hfc_dch_rx(hfctmp); | |
851 | if (hfctmp->ztdev->chans[2].bytes2receive > 0) { | |
852 | if (debug) { | |
853 | printk(KERN_CRIT "zaphfc: card %d RX [ ", hfctmp->cardno); | |
854 | @@ -757,19 +582,18 @@ | |
855 | if (hfctmp->ztdev->span.flags & ZT_FLAG_RUNNING) { | |
856 | zt_receive(&(hfctmp->ztdev->span)); | |
857 | } | |
858 | - | |
859 | -#ifndef RTAITIMING | |
860 | } | |
861 | -#endif | |
862 | + if(hfctmp!=hfctmp2)spin_unlock_irqrestore(&hfctmp->lock,flags2); | |
863 | + } | |
864 | + hfctmp=hfctmp->next; | |
865 | + } | |
866 | + hfctmp=hfctmp2; | |
867 | } | |
868 | - | |
869 | } | |
870 | -#ifndef RTAITIMING | |
871 | spin_unlock_irqrestore(&hfctmp->lock,flags); | |
872 | #ifdef LINUX26 | |
873 | return IRQ_RETVAL(1); | |
874 | #endif | |
875 | -#endif | |
876 | } | |
877 | ||
878 | ||
879 | @@ -826,22 +650,21 @@ | |
880 | } | |
881 | alreadyrunning = span->flags & ZT_FLAG_RUNNING; | |
882 | ||
883 | - if (!alreadyrunning) { | |
884 | - span->chans[2].flags &= ~ZT_FLAG_HDLC; | |
885 | - span->chans[2].flags |= ZT_FLAG_BRIDCHAN; | |
886 | - | |
887 | - span->flags |= ZT_FLAG_RUNNING; | |
888 | + if (alreadyrunning) return 0; | |
889 | ||
890 | - hfctmp->ticks = -2; | |
891 | - hfctmp->clicks = 0; | |
892 | - hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2; | |
893 | - hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en); | |
894 | - } else { | |
895 | - return 0; | |
896 | - } | |
897 | + span->chans[2].flags &= ~ZT_FLAG_HDLC; | |
898 | + span->chans[2].flags |= ZT_FLAG_BRIDCHAN; | |
899 | + | |
900 | + span->flags |= ZT_FLAG_RUNNING; | |
901 | + | |
902 | + hfctmp->ticks = -2; | |
903 | + hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2; | |
904 | + hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en); | |
905 | ||
906 | + hfc_bch_init(hfctmp); | |
907 | // drivers, start engines! | |
908 | hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE); | |
909 | + hfctmp->active=1; | |
910 | return 0; | |
911 | } | |
912 | ||
913 | @@ -871,17 +694,9 @@ | |
914 | ||
915 | sprintf(zthfc->span.name, "ZTHFC%d", hfc_dev_count + 1); | |
916 | if (hfctmp->regs.nt_mode == 1) { | |
917 | -#ifdef RTAITIMING | |
918 | - sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] [realtime]", hfc_dev_count + 1); | |
919 | -#else | |
920 | sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT]", hfc_dev_count + 1); | |
921 | -#endif | |
922 | } else { | |
923 | -#ifdef RTAITIMING | |
924 | - sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] [realtime]", hfc_dev_count + 1); | |
925 | -#else | |
926 | sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE]", hfc_dev_count + 1); | |
927 | -#endif | |
928 | } | |
929 | ||
930 | zthfc->span.spanconfig = zthfc_spanconfig; | |
931 | @@ -918,32 +733,6 @@ | |
932 | return 0; | |
933 | } | |
934 | ||
935 | -#ifdef RTAITIMING | |
936 | -#define TICK_PERIOD 1000000 | |
937 | -#define TICK_PERIOD2 1000000000 | |
938 | -#define TASK_PRIORITY 1 | |
939 | -#define STACK_SIZE 10000 | |
940 | - | |
941 | -static RT_TASK rt_task; | |
942 | -static struct hfc_card *rtai_hfc_list[hfc_MAX_CARDS]; | |
943 | -static unsigned char rtai_hfc_counter = 0; | |
944 | - | |
945 | -static void rtai_register_hfc(struct hfc_card *hfctmp) { | |
946 | - rtai_hfc_list[rtai_hfc_counter++] = hfctmp; | |
947 | -} | |
948 | - | |
949 | -static void rtai_loop(int t) { | |
950 | - int i=0; | |
951 | - for (;;) { | |
952 | - for (i=0; i < rtai_hfc_counter; i++) { | |
953 | - if (rtai_hfc_list[i] != NULL) | |
954 | - hfc_service(rtai_hfc_list[i]); | |
955 | - } | |
956 | - rt_task_wait_period(); | |
957 | - } | |
958 | -} | |
959 | -#endif | |
960 | - | |
961 | int hfc_findCards(int pcivendor, int pcidevice, char *vendor_name, char *card_name) { | |
962 | struct pci_dev *tmp; | |
963 | struct hfc_card *hfctmp = NULL; | |
964 | @@ -959,9 +748,9 @@ | |
965 | } | |
966 | pci_set_master(tmp); | |
967 | ||
968 | - hfctmp = kmalloc(sizeof(struct hfc_card), GFP_KERNEL); | |
969 | + hfctmp = vmalloc(sizeof(struct hfc_card)); | |
970 | if (!hfctmp) { | |
971 | - printk(KERN_WARNING "zaphfc: unable to kmalloc!\n"); | |
972 | + printk(KERN_WARNING "zaphfc: unable to vmalloc!\n"); | |
973 | pci_disable_device(tmp); | |
974 | multi_hfc = NULL; | |
975 | return -ENOMEM; | |
976 | @@ -969,6 +758,7 @@ | |
977 | memset(hfctmp, 0x0, sizeof(struct hfc_card)); | |
978 | spin_lock_init(&hfctmp->lock); | |
979 | ||
980 | + hfctmp->active=0; | |
981 | hfctmp->pcidev = tmp; | |
982 | hfctmp->pcibus = tmp->bus->number; | |
983 | hfctmp->pcidevfn = tmp->devfn; | |
984 | @@ -982,49 +772,39 @@ | |
985 | hfctmp->pci_io = (char *) tmp->resource[1].start; | |
986 | if (!hfctmp->pci_io) { | |
987 | printk(KERN_WARNING "zaphfc: no iomem!\n"); | |
988 | - kfree(hfctmp); | |
989 | + vfree(hfctmp); | |
990 | pci_disable_device(tmp); | |
991 | multi_hfc = NULL; | |
992 | return -1; | |
993 | } | |
994 | - | |
995 | - hfctmp->fifomem = kmalloc(65536, GFP_KERNEL); | |
996 | - if (!hfctmp->fifomem) { | |
997 | - printk(KERN_WARNING "zaphfc: unable to kmalloc fifomem!\n"); | |
998 | - kfree(hfctmp); | |
999 | + | |
1000 | + hfctmp->fifos=(void *)__get_free_pages(GFP_KERNEL,log2(hfc_FIFO_MEM_SIZE_PAGES)); | |
1001 | + if (!hfctmp->fifos) { | |
1002 | + printk(KERN_WARNING "zaphfc: unable to __get_free_pages fifomem!\n"); | |
1003 | + vfree(hfctmp); | |
1004 | pci_disable_device(tmp); | |
1005 | multi_hfc = NULL; | |
1006 | return -ENOMEM; | |
1007 | } else { | |
1008 | - memset(hfctmp->fifomem, 0x0, 65536); | |
1009 | - hfctmp->fifos = (void *)(((ulong) hfctmp->fifomem) & ~0x7FFF) + 0x8000; | |
1010 | pci_write_config_dword(hfctmp->pcidev, 0x80, (u_int) virt_to_bus(hfctmp->fifos)); | |
1011 | hfctmp->pci_io = ioremap((ulong) hfctmp->pci_io, 256); | |
1012 | } | |
1013 | ||
1014 | -#ifdef RTAITIMING | |
1015 | - /* we need no stinking irq */ | |
1016 | - hfctmp->irq = 0; | |
1017 | -#else | |
1018 | if (request_irq(hfctmp->irq, &hfc_interrupt, SA_INTERRUPT | SA_SHIRQ, "zaphfc", hfctmp)) { | |
1019 | printk(KERN_WARNING "zaphfc: unable to register irq\n"); | |
1020 | - kfree(hfctmp->fifomem); | |
1021 | - kfree(hfctmp); | |
1022 | + free_pages((unsigned long)hfctmp->fifos,log2(hfc_FIFO_MEM_SIZE_PAGES)); | |
1023 | + vfree(hfctmp); | |
1024 | iounmap((void *) hfctmp->pci_io); | |
1025 | pci_disable_device(tmp); | |
1026 | multi_hfc = NULL; | |
1027 | return -EIO; | |
1028 | } | |
1029 | -#endif | |
1030 | ||
1031 | -#ifdef RTAITIMING | |
1032 | - rtai_register_hfc(hfctmp); | |
1033 | -#endif | |
1034 | printk(KERN_INFO | |
1035 | - "zaphfc: %s %s configured at mem %lx fifo %lx(%#x) IRQ %d HZ %d\n", | |
1036 | + "zaphfc: %s %s configured at mem %#x fifo %#x(%#x) IRQ %d HZ %d\n", | |
1037 | vendor_name, card_name, | |
1038 | - (unsigned long) hfctmp->pci_io, | |
1039 | - (unsigned long) hfctmp->fifos, | |
1040 | + (u_int) hfctmp->pci_io, | |
1041 | + (u_int) hfctmp->fifos, | |
1042 | (u_int) virt_to_bus(hfctmp->fifos), | |
1043 | hfctmp->irq, HZ); | |
1044 | pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY); // enable memio | |
1045 | @@ -1041,11 +821,21 @@ | |
1046 | hfctmp->regs.nt_mode = 0; | |
1047 | } | |
1048 | ||
1049 | - zthfc = kmalloc(sizeof(struct zt_hfc),GFP_KERNEL); | |
1050 | + if(sync_slave&(1<<hfc_dev_count)){ | |
1051 | + printk(KERN_INFO "zaphfc: Card %d configured for slave mode\n",hfc_dev_count); | |
1052 | + hfctmp->regs.mst_mode=hfc_MST_MODE_SLAVE|hfc_MST_MODE_F0_LONG_DURATION; | |
1053 | + hfctmp->regs.mst_emod=hfc_MST_EMOD_SLOW_CLOCK_ADJ; | |
1054 | + }else{ | |
1055 | + printk(KERN_INFO "zaphfc: Card %d configured for master mode\n",hfc_dev_count); | |
1056 | + hfctmp->regs.mst_mode=hfc_MST_MODE_MASTER|hfc_MST_MODE_F0_LONG_DURATION; | |
1057 | + hfctmp->regs.mst_emod=0; | |
1058 | + } | |
1059 | + | |
1060 | + zthfc = vmalloc(sizeof(struct zt_hfc)); | |
1061 | if (!zthfc) { | |
1062 | - printk(KERN_CRIT "zaphfc: unable to kmalloc!\n"); | |
1063 | + printk(KERN_CRIT "zaphfc: unable to vmalloc!\n"); | |
1064 | hfc_shutdownCard(hfctmp); | |
1065 | - kfree(hfctmp); | |
1066 | + vfree(hfctmp); | |
1067 | multi_hfc = NULL; | |
1068 | return -ENOMEM; | |
1069 | } | |
1070 | @@ -1071,7 +861,6 @@ | |
1071 | memset(hfctmp->btransbuf[1], 0x0, sizeof(hfctmp->btransbuf[1])); | |
1072 | hfctmp->ztdev->chans[1].writechunk = hfctmp->btransbuf[1]; | |
1073 | ||
1074 | - | |
1075 | hfc_registerCard(hfctmp); | |
1076 | hfc_resetCard(hfctmp); | |
1077 | tmp = pci_find_device(pcivendor, pcidevice, multi_hfc); | |
1078 | @@ -1079,58 +868,42 @@ | |
1079 | return 0; | |
1080 | } | |
1081 | ||
1082 | - | |
1083 | - | |
1084 | int init_module(void) { | |
1085 | int i = 0; | |
1086 | -#ifdef RTAITIMING | |
1087 | - RTIME tick_period; | |
1088 | - for (i=0; i < hfc_MAX_CARDS; i++) { | |
1089 | - rtai_hfc_list[i] = NULL; | |
1090 | + if(jitterbuffer<1){ | |
1091 | + printk(KERN_INFO "zaphfc: invalid jitterbuffer size specified: %d - changing to minimum of 1\n",jitterbuffer); | |
1092 | + jitterbuffer=1; | |
1093 | + }else if(jitterbuffer>500){ | |
1094 | + printk(KERN_INFO "zaphfc: invalid jitterbuffer size specified: %d - changing to maximum of 500\n",jitterbuffer); | |
1095 | + jitterbuffer=500; | |
1096 | } | |
1097 | - rt_set_periodic_mode(); | |
1098 | -#endif | |
1099 | - i = 0; | |
1100 | + printk(KERN_INFO "zaphfc: jitterbuffer size: %d\n",jitterbuffer); | |
1101 | while (id_list[i].vendor_id) { | |
1102 | multi_hfc = NULL; | |
1103 | hfc_findCards(id_list[i].vendor_id, id_list[i].device_id, id_list[i].vendor_name, id_list[i].card_name); | |
1104 | i++; | |
1105 | } | |
1106 | -#ifdef RTAITIMING | |
1107 | - for (i=0; i < hfc_MAX_CARDS; i++) { | |
1108 | - if (rtai_hfc_list[i]) { | |
1109 | - printk(KERN_INFO | |
1110 | - "zaphfc: configured %d at mem %#x fifo %#x(%#x) for realtime servicing\n", | |
1111 | - rtai_hfc_list[i]->cardno, | |
1112 | - (u_int) rtai_hfc_list[i]->pci_io, | |
1113 | - (u_int) rtai_hfc_list[i]->fifos, | |
1114 | - (u_int) virt_to_bus(rtai_hfc_list[i]->fifos)); | |
1115 | - | |
1116 | - } | |
1117 | - } | |
1118 | - rt_task_init(&rt_task, rtai_loop, 1, STACK_SIZE, TASK_PRIORITY, 0, 0); | |
1119 | - tick_period = start_rt_timer(nano2count(TICK_PERIOD)); | |
1120 | - rt_task_make_periodic(&rt_task, rt_get_time() + tick_period, tick_period); | |
1121 | -#endif | |
1122 | printk(KERN_INFO "zaphfc: %d hfc-pci card(s) in this box.\n", hfc_dev_count); | |
1123 | return 0; | |
1124 | } | |
1125 | ||
1126 | void cleanup_module(void) { | |
1127 | struct hfc_card *tmpcard; | |
1128 | -#ifdef RTAITIMING | |
1129 | - stop_rt_timer(); | |
1130 | - rt_task_delete(&rt_task); | |
1131 | -#endif | |
1132 | + | |
1133 | printk(KERN_INFO "zaphfc: stop\n"); | |
1134 | // spin_lock(®isterlock); | |
1135 | + tmpcard=hfc_dev_list; | |
1136 | + while(tmpcard){ | |
1137 | + hfc_shutdownCard1(tmpcard); | |
1138 | + tmpcard=tmpcard->next; | |
1139 | + } | |
1140 | while (hfc_dev_list != NULL) { | |
1141 | if (hfc_dev_list == NULL) break; | |
1142 | - hfc_shutdownCard(hfc_dev_list); | |
1143 | + hfc_shutdownCard2(hfc_dev_list); | |
1144 | tmpcard = hfc_dev_list; | |
1145 | hfc_dev_list = hfc_dev_list->next; | |
1146 | if (tmpcard != NULL) { | |
1147 | - kfree(tmpcard); | |
1148 | + vfree(tmpcard); | |
1149 | tmpcard = NULL; | |
1150 | printk(KERN_INFO "zaphfc: freed one card.\n"); | |
1151 | } | |
1152 | @@ -1141,11 +914,17 @@ | |
1153 | ||
1154 | ||
1155 | #ifdef LINUX26 | |
1156 | -module_param(modes, int, 0600); | |
1157 | +module_param(modes, int, 0400); | |
1158 | module_param(debug, int, 0600); | |
1159 | +module_param(sync_slave, int, 0400); | |
1160 | +module_param(timer_card, int, 0400); | |
1161 | +module_param(jitterbuffer, int, 0400); | |
1162 | #else | |
1163 | MODULE_PARM(modes,"i"); | |
1164 | MODULE_PARM(debug,"i"); | |
1165 | +MODULE_PARM(sync_slave,"i"); | |
1166 | +MODULE_PARM(timer_card,"i"); | |
1167 | +MODULE_PARM(jitterbuffer,"i"); | |
1168 | #endif | |
1169 | ||
1170 | MODULE_DESCRIPTION("HFC-S PCI A Zaptel Driver"); | |
1171 | @@ -1153,3 +932,6 @@ | |
1172 | #ifdef MODULE_LICENSE | |
1173 | MODULE_LICENSE("GPL"); | |
1174 | #endif | |
1175 | + | |
1176 | +/* vim:set sw=4: */ | |
1177 | + | |
1178 | diff -urN bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.h zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.h | |
1179 | --- bristuff-0.3.0-PRE-1o/zaphfc/zaphfc.h 2005-02-26 23:30:32.000000000 +0100 | |
1180 | +++ zaphfc_0.3.0-PRE-1o_florz-12/zaphfc.h 2005-03-02 20:43:04.000000000 +0100 | |
1181 | @@ -135,8 +135,12 @@ | |
1182 | /* bits in HFCD_MST_MODE */ | |
1183 | #define hfc_MST_MODE_MASTER 0x01 | |
1184 | #define hfc_MST_MODE_SLAVE 0x00 | |
1185 | +#define hfc_MST_MODE_F0_LONG_DURATION 0x08 | |
1186 | /* remaining bits are for codecs control */ | |
1187 | ||
1188 | +/* bits in HFCD_MST_EMOD */ | |
1189 | +#define hfc_MST_EMOD_SLOW_CLOCK_ADJ 0x01 | |
1190 | + | |
1191 | /* bits in HFCD_SCTRL */ | |
1192 | #define hfc_SCTRL_B1_ENA 0x01 | |
1193 | #define hfc_SCTRL_B2_ENA 0x02 | |
1194 | @@ -236,6 +240,9 @@ | |
1195 | #define hfc_BTRANS_THRESHOLD 128 | |
1196 | #define hfc_BTRANS_THRESMASK 0x00 | |
1197 | ||
1198 | +#define hfc_FIFO_MEM_SIZE_BYTES (32*1024) | |
1199 | +#define hfc_FIFO_MEM_SIZE_PAGES ((hfc_FIFO_MEM_SIZE_BYTES+PAGE_SIZE-1)/PAGE_SIZE) | |
1200 | + | |
1201 | /* Structures */ | |
1202 | ||
1203 | typedef struct hfc_regs { | |
1204 | @@ -249,20 +256,67 @@ | |
1205 | unsigned char connect; | |
1206 | unsigned char trm; | |
1207 | unsigned char mst_mode; | |
1208 | + unsigned char mst_emod; | |
1209 | unsigned char bswapped; | |
1210 | unsigned char nt_mode; | |
1211 | unsigned char int_drec; | |
1212 | } hfc_regs; | |
1213 | ||
1214 | +struct bch { | |
1215 | + int fill_fifo,checkcnt,initialized; | |
1216 | + struct { | |
1217 | + u16 z2; | |
1218 | + struct { | |
1219 | + volatile u16 *z1p; | |
1220 | + volatile u8 *fifo_base; | |
1221 | + int filled; | |
1222 | + } c[2]; | |
1223 | + int diff; | |
1224 | + } rx; | |
1225 | + struct { | |
1226 | + u16 z1; | |
1227 | + struct { | |
1228 | + volatile u16 *z1p,*z2p; | |
1229 | + volatile u8 *fifo_base; | |
1230 | + int filled; | |
1231 | + } c[2]; | |
1232 | + int diff; | |
1233 | + } tx; | |
1234 | +}; | |
1235 | + | |
1236 | +struct dch { | |
1237 | + struct { | |
1238 | + struct { | |
1239 | + volatile u8 *p; | |
1240 | + } f1; | |
1241 | + struct { | |
1242 | + u8 v; | |
1243 | + struct { | |
1244 | + u16 v; | |
1245 | + } z2; | |
1246 | + } f2; | |
1247 | + } rx; | |
1248 | + struct { | |
1249 | + struct { | |
1250 | + u8 v; | |
1251 | + volatile u8 *p; | |
1252 | + struct { | |
1253 | + u16 v; | |
1254 | + } z1; | |
1255 | + } f1; | |
1256 | + struct { | |
1257 | + volatile u8 *p; | |
1258 | + } f2; | |
1259 | + } tx; | |
1260 | +}; | |
1261 | + | |
1262 | typedef struct hfc_card { | |
1263 | spinlock_t lock; | |
1264 | unsigned int irq; | |
1265 | unsigned int iomem; | |
1266 | int ticks; | |
1267 | - int clicks; | |
1268 | unsigned char *pci_io; | |
1269 | - void *fifomem; // start of the shared mem | |
1270 | - volatile void *fifos; // 32k aligned mem for the fifos | |
1271 | + void *fifos; // 32k aligned mem for the fifos | |
1272 | struct hfc_regs regs; | |
1273 | unsigned int pcibus; | |
1274 | unsigned int pcidevfn; | |
1275 | @@ -274,6 +328,9 @@ | |
1276 | unsigned char brecbuf[2][ZT_CHUNKSIZE]; | |
1277 | unsigned char btransbuf[2][ZT_CHUNKSIZE]; | |
1278 | unsigned char cardno; | |
1279 | + int active; | |
1280 | + struct bch bch; | |
1281 | + struct dch dch; | |
1282 | struct hfc_card *next; | |
1283 | } hfc_card; | |
1284 | ||
1285 | @@ -284,6 +341,5 @@ | |
1286 | struct hfc_card *card; | |
1287 | } zt_hfc; | |
1288 | ||
1289 | -/* tune this */ | |
1290 | -#define hfc_BCHAN_BUFFER 8 | |
1291 | -#define hfc_MAX_CARDS 8 | |
1292 | +/* vim:set sw=4: */ | |
1293 | + |