diff options
author | Andreas Eversberg <andreas@eversberg.eu> | 2008-09-28 07:01:01 -0400 |
---|---|---|
committer | Karsten Keil <kkeil@suse.de> | 2009-01-09 16:44:28 -0500 |
commit | 87c5fa1bb42624254a2013cbbc3b170d6017f5d6 (patch) | |
tree | 49772208b9e511d233e6b715b44fb4062fe1760f /drivers/isdn/hardware | |
parent | 1b36c78f26bfa74c1782be98acb827afa95c3b0c (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/isdn/hardware')
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfc_pci.h | 1 | ||||
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfcpci.c | 152 |
2 files changed, 125 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 | ||
37 | static int HFC_cnt; | 56 | static int HFC_cnt; |
38 | static uint debug; | 57 | static uint debug; |
58 | static uint poll, tics; | ||
59 | struct timer_list hfc_tl; | ||
60 | u32 hfc_jiffies; | ||
39 | 61 | ||
40 | MODULE_AUTHOR("Karsten Keil"); | 62 | MODULE_AUTHOR("Karsten Keil"); |
41 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
42 | module_param(debug, uint, 0); | 64 | module_param(debug, uint, 0); |
65 | module_param(poll, uint, S_IRUGO | S_IWUSR); | ||
43 | 66 | ||
44 | static LIST_HEAD(HFClist); | 67 | static LIST_HEAD(HFClist); |
45 | static DEFINE_RWLOCK(HFClock); | 68 | static 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 | */ |
524 | static int | 547 | static void |
525 | hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata) | 548 | hfcpci_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 | ||
783 | next_t_frame: | 807 | next_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 | ||
1230 | static void | ||
1231 | hfcpci_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 | } |