aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndreas Eversberg <andreas@eversberg.eu>2008-09-28 07:01:01 -0400
committerKarsten Keil <kkeil@suse.de>2009-01-09 16:44:28 -0500
commit87c5fa1bb42624254a2013cbbc3b170d6017f5d6 (patch)
tree49772208b9e511d233e6b715b44fb4062fe1760f /drivers
parent1b36c78f26bfa74c1782be98acb827afa95c3b0c (diff)
mISDN: Add different different timer settings for hfc-pci
- Poll-timer can now be set from 8 to 256 samples, depending on your kernel. - If default or 128 is used, the normal controller's clock is used as before. Usage: modprobe hfcpci poll=XXX - Added some debug code for dsp buffer size. (CMX_DELAY_DEBUG) Signed-off-by: Andreas Eversberg <andreas@eversberg.eu> Signed-off-by: Karsten Keil <kkeil@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/isdn/hardware/mISDN/hfc_pci.h1
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c152
-rw-r--r--drivers/isdn/mISDN/dsp_cmx.c23
3 files changed, 148 insertions, 28 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfc_pci.h b/drivers/isdn/hardware/mISDN/hfc_pci.h
index fd9241ab1802..3132ddc99fcd 100644
--- a/drivers/isdn/hardware/mISDN/hfc_pci.h
+++ b/drivers/isdn/hardware/mISDN/hfc_pci.h
@@ -26,7 +26,6 @@
26 * change mask and threshold simultaneously 26 * change mask and threshold simultaneously
27 */ 27 */
28#define HFCPCI_BTRANS_THRESHOLD 128 28#define HFCPCI_BTRANS_THRESHOLD 128
29#define HFCPCI_BTRANS_MAX 256
30#define HFCPCI_FILLEMPTY 64 29#define HFCPCI_FILLEMPTY 64
31#define HFCPCI_BTRANS_THRESMASK 0x00 30#define HFCPCI_BTRANS_THRESMASK 0x00
32 31
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index ea69d5862f6d..cd5d26c9909f 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -23,6 +23,25 @@
23 * along with this program; if not, write to the Free Software 23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * 25 *
26 * Module options:
27 *
28 * debug:
29 * NOTE: only one poll value must be given for all cards
30 * See hfc_pci.h for debug flags.
31 *
32 * poll:
33 * NOTE: only one poll value must be given for all cards
34 * Give the number of samples for each fifo process.
35 * By default 128 is used. Decrease to reduce delay, increase to
36 * reduce cpu load. If unsure, don't mess with it!
37 * A value of 128 will use controller's interrupt. Other values will
38 * use kernel timer, because the controller will not allow lower values
39 * than 128.
40 * Also note that the value depends on the kernel timer frequency.
41 * If kernel uses a frequency of 1000 Hz, steps of 8 samples are possible.
42 * If the kernel uses 100 Hz, steps of 80 samples are possible.
43 * If the kernel uses 300 Hz, steps of about 26 samples are possible.
44 *
26 */ 45 */
27 46
28#include <linux/module.h> 47#include <linux/module.h>
@@ -36,10 +55,14 @@ static const char *hfcpci_revision = "2.0";
36 55
37static int HFC_cnt; 56static int HFC_cnt;
38static uint debug; 57static uint debug;
58static uint poll, tics;
59struct timer_list hfc_tl;
60u32 hfc_jiffies;
39 61
40MODULE_AUTHOR("Karsten Keil"); 62MODULE_AUTHOR("Karsten Keil");
41MODULE_LICENSE("GPL"); 63MODULE_LICENSE("GPL");
42module_param(debug, uint, 0); 64module_param(debug, uint, 0);
65module_param(poll, uint, S_IRUGO | S_IWUSR);
43 66
44static LIST_HEAD(HFClist); 67static LIST_HEAD(HFClist);
45static DEFINE_RWLOCK(HFClock); 68static DEFINE_RWLOCK(HFClock);
@@ -519,9 +542,9 @@ receive_dmsg(struct hfc_pci *hc)
519} 542}
520 543
521/* 544/*
522 * check for transparent receive data and read max one threshold size if avail 545 * check for transparent receive data and read max one 'poll' size if avail
523 */ 546 */
524static int 547static void
525hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata) 548hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata)
526{ 549{
527 __le16 *z1r, *z2r; 550 __le16 *z1r, *z2r;
@@ -533,17 +556,19 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata)
533 556
534 fcnt = le16_to_cpu(*z1r) - le16_to_cpu(*z2r); 557 fcnt = le16_to_cpu(*z1r) - le16_to_cpu(*z2r);
535 if (!fcnt) 558 if (!fcnt)
536 return 0; /* no data avail */ 559 return; /* no data avail */
537 560
538 if (fcnt <= 0) 561 if (fcnt <= 0)
539 fcnt += B_FIFO_SIZE; /* bytes actually buffered */ 562 fcnt += B_FIFO_SIZE; /* bytes actually buffered */
540 if (fcnt > HFCPCI_BTRANS_THRESHOLD)
541 fcnt = HFCPCI_BTRANS_THRESHOLD; /* limit size */
542
543 new_z2 = le16_to_cpu(*z2r) + fcnt; /* new position in fifo */ 563 new_z2 = le16_to_cpu(*z2r) + fcnt; /* new position in fifo */
544 if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) 564 if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL))
545 new_z2 -= B_FIFO_SIZE; /* buffer wrap */ 565 new_z2 -= B_FIFO_SIZE; /* buffer wrap */
546 566
567 if (fcnt > MAX_DATA_SIZE) { /* flush, if oversized */
568 *z2r = cpu_to_le16(new_z2); /* new position */
569 return;
570 }
571
547 bch->rx_skb = mI_alloc_skb(fcnt, GFP_ATOMIC); 572 bch->rx_skb = mI_alloc_skb(fcnt, GFP_ATOMIC);
548 if (bch->rx_skb) { 573 if (bch->rx_skb) {
549 ptr = skb_put(bch->rx_skb, fcnt); 574 ptr = skb_put(bch->rx_skb, fcnt);
@@ -568,7 +593,6 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata)
568 printk(KERN_WARNING "HFCPCI: receive out of memory\n"); 593 printk(KERN_WARNING "HFCPCI: receive out of memory\n");
569 594
570 *z2r = cpu_to_le16(new_z2); /* new position */ 595 *z2r = cpu_to_le16(new_z2); /* new position */
571 return 1;
572} 596}
573 597
574/* 598/*
@@ -579,12 +603,11 @@ main_rec_hfcpci(struct bchannel *bch)
579{ 603{
580 struct hfc_pci *hc = bch->hw; 604 struct hfc_pci *hc = bch->hw;
581 int rcnt, real_fifo; 605 int rcnt, real_fifo;
582 int receive, count = 5; 606 int receive = 0, count = 5;
583 struct bzfifo *bz; 607 struct bzfifo *bz;
584 u_char *bdata; 608 u_char *bdata;
585 struct zt *zp; 609 struct zt *zp;
586 610
587
588 if ((bch->nr & 2) && (!hc->hw.bswapped)) { 611 if ((bch->nr & 2) && (!hc->hw.bswapped)) {
589 bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2; 612 bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2;
590 bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2; 613 bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2;
@@ -624,9 +647,10 @@ Begin:
624 receive = 1; 647 receive = 1;
625 else 648 else
626 receive = 0; 649 receive = 0;
627 } else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) 650 } else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
628 receive = hfcpci_empty_fifo_trans(bch, bz, bdata); 651 hfcpci_empty_fifo_trans(bch, bz, bdata);
629 else 652 return;
653 } else
630 receive = 0; 654 receive = 0;
631 if (count && receive) 655 if (count && receive)
632 goto Begin; 656 goto Begin;
@@ -782,9 +806,9 @@ hfcpci_fill_fifo(struct bchannel *bch)
782 806
783next_t_frame: 807next_t_frame:
784 count = bch->tx_skb->len - bch->tx_idx; 808 count = bch->tx_skb->len - bch->tx_idx;
785 /* maximum fill shall be HFCPCI_BTRANS_MAX */ 809 /* maximum fill shall be poll*2 */
786 if (count > HFCPCI_BTRANS_MAX - fcnt) 810 if (count > (poll << 1) - fcnt)
787 count = HFCPCI_BTRANS_MAX - fcnt; 811 count = (poll << 1) - fcnt;
788 if (count <= 0) 812 if (count <= 0)
789 return; 813 return;
790 /* data is suitable for fifo */ 814 /* data is suitable for fifo */
@@ -1164,37 +1188,37 @@ hfcpci_int(int intno, void *dev_id)
1164 val &= ~0x80; 1188 val &= ~0x80;
1165 Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | HFCPCI_CLTIMER); 1189 Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | HFCPCI_CLTIMER);
1166 } 1190 }
1167 if (val & 0x08) { 1191 if (val & 0x08) { /* B1 rx */
1168 bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); 1192 bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
1169 if (bch) 1193 if (bch)
1170 main_rec_hfcpci(bch); 1194 main_rec_hfcpci(bch);
1171 else if (hc->dch.debug) 1195 else if (hc->dch.debug)
1172 printk(KERN_DEBUG "hfcpci spurious 0x08 IRQ\n"); 1196 printk(KERN_DEBUG "hfcpci spurious 0x08 IRQ\n");
1173 } 1197 }
1174 if (val & 0x10) { 1198 if (val & 0x10) { /* B2 rx */
1175 bch = Sel_BCS(hc, 2); 1199 bch = Sel_BCS(hc, 2);
1176 if (bch) 1200 if (bch)
1177 main_rec_hfcpci(bch); 1201 main_rec_hfcpci(bch);
1178 else if (hc->dch.debug) 1202 else if (hc->dch.debug)
1179 printk(KERN_DEBUG "hfcpci spurious 0x10 IRQ\n"); 1203 printk(KERN_DEBUG "hfcpci spurious 0x10 IRQ\n");
1180 } 1204 }
1181 if (val & 0x01) { 1205 if (val & 0x01) { /* B1 tx */
1182 bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); 1206 bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
1183 if (bch) 1207 if (bch)
1184 tx_birq(bch); 1208 tx_birq(bch);
1185 else if (hc->dch.debug) 1209 else if (hc->dch.debug)
1186 printk(KERN_DEBUG "hfcpci spurious 0x01 IRQ\n"); 1210 printk(KERN_DEBUG "hfcpci spurious 0x01 IRQ\n");
1187 } 1211 }
1188 if (val & 0x02) { 1212 if (val & 0x02) { /* B2 tx */
1189 bch = Sel_BCS(hc, 2); 1213 bch = Sel_BCS(hc, 2);
1190 if (bch) 1214 if (bch)
1191 tx_birq(bch); 1215 tx_birq(bch);
1192 else if (hc->dch.debug) 1216 else if (hc->dch.debug)
1193 printk(KERN_DEBUG "hfcpci spurious 0x02 IRQ\n"); 1217 printk(KERN_DEBUG "hfcpci spurious 0x02 IRQ\n");
1194 } 1218 }
1195 if (val & 0x20) 1219 if (val & 0x20) /* D rx */
1196 receive_dmsg(hc); 1220 receive_dmsg(hc);
1197 if (val & 0x04) { /* dframe transmitted */ 1221 if (val & 0x04) { /* D tx */
1198 if (test_and_clear_bit(FLG_BUSY_TIMER, &hc->dch.Flags)) 1222 if (test_and_clear_bit(FLG_BUSY_TIMER, &hc->dch.Flags))
1199 del_timer(&hc->dch.timer); 1223 del_timer(&hc->dch.timer);
1200 tx_dirq(&hc->dch); 1224 tx_dirq(&hc->dch);
@@ -1203,6 +1227,41 @@ hfcpci_int(int intno, void *dev_id)
1203 return IRQ_HANDLED; 1227 return IRQ_HANDLED;
1204} 1228}
1205 1229
1230static void
1231hfcpci_softirq(void *arg)
1232{
1233 u_long flags;
1234 struct bchannel *bch;
1235 struct hfc_pci *hc;
1236
1237 write_lock_irqsave(&HFClock, flags);
1238 list_for_each_entry(hc, &HFClist, list) {
1239 if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) {
1240 spin_lock(&hc->lock);
1241 bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1);
1242 if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */
1243 main_rec_hfcpci(bch);
1244 tx_birq(bch);
1245 }
1246 bch = Sel_BCS(hc, hc->hw.bswapped ? 1 : 2);
1247 if (bch && bch->state == ISDN_P_B_RAW) { /* B2 rx&tx */
1248 main_rec_hfcpci(bch);
1249 tx_birq(bch);
1250 }
1251 spin_unlock(&hc->lock);
1252 }
1253 }
1254 write_unlock_irqrestore(&HFClock, flags);
1255
1256 /* if next event would be in the past ... */
1257 if ((s32)(hfc_jiffies + tics - jiffies) <= 0)
1258 hfc_jiffies = jiffies + 1;
1259 else
1260 hfc_jiffies += tics;
1261 hfc_tl.expires = hfc_jiffies;
1262 add_timer(&hfc_tl);
1263}
1264
1206/* 1265/*
1207 * timer callback for D-chan busy resolution. Currently no function 1266 * timer callback for D-chan busy resolution. Currently no function
1208 */ 1267 */
@@ -1312,14 +1371,16 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
1312 } 1371 }
1313 if (fifo2 & 2) { 1372 if (fifo2 & 2) {
1314 hc->hw.fifo_en |= HFCPCI_FIFOEN_B2; 1373 hc->hw.fifo_en |= HFCPCI_FIFOEN_B2;
1315 hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS + 1374 if (!tics)
1316 HFCPCI_INTS_B2REC); 1375 hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS +
1376 HFCPCI_INTS_B2REC);
1317 hc->hw.ctmt |= 2; 1377 hc->hw.ctmt |= 2;
1318 hc->hw.conn &= ~0x18; 1378 hc->hw.conn &= ~0x18;
1319 } else { 1379 } else {
1320 hc->hw.fifo_en |= HFCPCI_FIFOEN_B1; 1380 hc->hw.fifo_en |= HFCPCI_FIFOEN_B1;
1321 hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS + 1381 if (!tics)
1322 HFCPCI_INTS_B1REC); 1382 hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS +
1383 HFCPCI_INTS_B1REC);
1323 hc->hw.ctmt |= 1; 1384 hc->hw.ctmt |= 1;
1324 hc->hw.conn &= ~0x03; 1385 hc->hw.conn &= ~0x03;
1325 } 1386 }
@@ -1427,7 +1488,8 @@ set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan)
1427 if (chan & 2) { 1488 if (chan & 2) {
1428 hc->hw.sctrl_r |= SCTRL_B2_ENA; 1489 hc->hw.sctrl_r |= SCTRL_B2_ENA;
1429 hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX; 1490 hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX;
1430 hc->hw.int_m1 |= HFCPCI_INTS_B2REC; 1491 if (!tics)
1492 hc->hw.int_m1 |= HFCPCI_INTS_B2REC;
1431 hc->hw.ctmt |= 2; 1493 hc->hw.ctmt |= 2;
1432 hc->hw.conn &= ~0x18; 1494 hc->hw.conn &= ~0x18;
1433#ifdef REVERSE_BITORDER 1495#ifdef REVERSE_BITORDER
@@ -1436,7 +1498,8 @@ set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan)
1436 } else { 1498 } else {
1437 hc->hw.sctrl_r |= SCTRL_B1_ENA; 1499 hc->hw.sctrl_r |= SCTRL_B1_ENA;
1438 hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX; 1500 hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX;
1439 hc->hw.int_m1 |= HFCPCI_INTS_B1REC; 1501 if (!tics)
1502 hc->hw.int_m1 |= HFCPCI_INTS_B1REC;
1440 hc->hw.ctmt |= 1; 1503 hc->hw.ctmt |= 1;
1441 hc->hw.conn &= ~0x03; 1504 hc->hw.conn &= ~0x03;
1442#ifdef REVERSE_BITORDER 1505#ifdef REVERSE_BITORDER
@@ -2273,7 +2336,39 @@ HFC_init(void)
2273{ 2336{
2274 int err; 2337 int err;
2275 2338
2339 if (!poll)
2340 poll = HFCPCI_BTRANS_THRESHOLD;
2341
2342 if (poll != HFCPCI_BTRANS_THRESHOLD) {
2343 tics = poll * HZ / 8000;
2344 if (tics < 1)
2345 tics = 1;
2346 poll = tics * 8000 / HZ;
2347 if (poll > 256 || poll < 8) {
2348 printk(KERN_ERR "%s: Wrong poll value %d not in range "
2349 "of 8..256.\n", __func__, poll);
2350 err = -EINVAL;
2351 return err;
2352 }
2353 }
2354 if (poll != HFCPCI_BTRANS_THRESHOLD) {
2355 printk(KERN_INFO "%s: Using alternative poll value of %d\n",
2356 __func__, poll);
2357 hfc_tl.function = (void *)hfcpci_softirq;
2358 hfc_tl.data = 0;
2359 init_timer(&hfc_tl);
2360 hfc_tl.expires = jiffies + tics;
2361 hfc_jiffies = hfc_tl.expires;
2362 add_timer(&hfc_tl);
2363 } else
2364 tics = 0; /* indicate the use of controller's timer */
2365
2276 err = pci_register_driver(&hfc_driver); 2366 err = pci_register_driver(&hfc_driver);
2367 if (err) {
2368 if (timer_pending(&hfc_tl))
2369 del_timer(&hfc_tl);
2370 }
2371
2277 return err; 2372 return err;
2278} 2373}
2279 2374
@@ -2282,6 +2377,9 @@ HFC_cleanup(void)
2282{ 2377{
2283 struct hfc_pci *card, *next; 2378 struct hfc_pci *card, *next;
2284 2379
2380 if (timer_pending(&hfc_tl))
2381 del_timer(&hfc_tl);
2382
2285 list_for_each_entry_safe(card, next, &HFClist, list) { 2383 list_for_each_entry_safe(card, next, &HFClist, list) {
2286 release_card(card); 2384 release_card(card);
2287 } 2385 }
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
index efe4c7430e6d..02f643456b16 100644
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -137,6 +137,7 @@
137/* #define CMX_CONF_DEBUG */ 137/* #define CMX_CONF_DEBUG */
138 138
139/*#define CMX_DEBUG * massive read/write pointer output */ 139/*#define CMX_DEBUG * massive read/write pointer output */
140/*#define CMX_DELAY_DEBUG * gives rx-buffer delay overview */
140/*#define CMX_TX_DEBUG * massive read/write on tx-buffer with content */ 141/*#define CMX_TX_DEBUG * massive read/write on tx-buffer with content */
141 142
142static inline int 143static inline int
@@ -1135,6 +1136,25 @@ dsp_cmx_conf(struct dsp *dsp, u32 conf_id)
1135 return 0; 1136 return 0;
1136} 1137}
1137 1138
1139#ifdef CMX_DELAY_DEBUG
1140int delaycount;
1141static void
1142showdelay(struct dsp *dsp, int samples, int delay)
1143{
1144 char bar[] = "--------------------------------------------------|";
1145 int sdelay;
1146
1147 delaycount += samples;
1148 if (delaycount < 8000)
1149 return;
1150 delaycount = 0;
1151
1152 sdelay = delay * 50 / (dsp_poll << 2);
1153
1154 printk(KERN_DEBUG "DELAY (%s) %3d >%s\n", dsp->name, delay,
1155 sdelay > 50 ? "..." : bar + 50 - sdelay);
1156}
1157#endif
1138 1158
1139/* 1159/*
1140 * audio data is received from card 1160 * audio data is received from card
@@ -1256,6 +1276,9 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
1256 1276
1257 /* increase write-pointer */ 1277 /* increase write-pointer */
1258 dsp->rx_W = ((dsp->rx_W+len) & CMX_BUFF_MASK); 1278 dsp->rx_W = ((dsp->rx_W+len) & CMX_BUFF_MASK);
1279#ifdef CMX_DELAY_DEBUG
1280 showdelay(dsp, len, (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK);
1281#endif
1259} 1282}
1260 1283
1261 1284