diff options
Diffstat (limited to 'drivers/isdn/hardware/mISDN/hfcpci.c')
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfcpci.c | 241 |
1 files changed, 186 insertions, 55 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index cd8302af40eb..f0e14dfcf71d 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> |
@@ -34,16 +53,16 @@ | |||
34 | 53 | ||
35 | static const char *hfcpci_revision = "2.0"; | 54 | static const char *hfcpci_revision = "2.0"; |
36 | 55 | ||
37 | #define MAX_CARDS 8 | ||
38 | static int HFC_cnt; | 56 | static int HFC_cnt; |
39 | static uint debug; | 57 | static uint debug; |
58 | static uint poll, tics; | ||
59 | struct timer_list hfc_tl; | ||
60 | u32 hfc_jiffies; | ||
40 | 61 | ||
41 | MODULE_AUTHOR("Karsten Keil"); | 62 | MODULE_AUTHOR("Karsten Keil"); |
42 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
43 | module_param(debug, uint, 0); | 64 | module_param(debug, uint, S_IRUGO | S_IWUSR); |
44 | 65 | module_param(poll, uint, S_IRUGO | S_IWUSR); | |
45 | static LIST_HEAD(HFClist); | ||
46 | static DEFINE_RWLOCK(HFClock); | ||
47 | 66 | ||
48 | enum { | 67 | enum { |
49 | HFC_CCD_2BD0, | 68 | HFC_CCD_2BD0, |
@@ -114,7 +133,6 @@ struct hfcPCI_hw { | |||
114 | 133 | ||
115 | 134 | ||
116 | struct hfc_pci { | 135 | struct hfc_pci { |
117 | struct list_head list; | ||
118 | u_char subtype; | 136 | u_char subtype; |
119 | u_char chanlimit; | 137 | u_char chanlimit; |
120 | u_char initdone; | 138 | u_char initdone; |
@@ -520,9 +538,9 @@ receive_dmsg(struct hfc_pci *hc) | |||
520 | } | 538 | } |
521 | 539 | ||
522 | /* | 540 | /* |
523 | * check for transparent receive data and read max one threshold size if avail | 541 | * check for transparent receive data and read max one 'poll' size if avail |
524 | */ | 542 | */ |
525 | static int | 543 | static void |
526 | hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata) | 544 | hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata) |
527 | { | 545 | { |
528 | __le16 *z1r, *z2r; | 546 | __le16 *z1r, *z2r; |
@@ -534,17 +552,19 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata) | |||
534 | 552 | ||
535 | fcnt = le16_to_cpu(*z1r) - le16_to_cpu(*z2r); | 553 | fcnt = le16_to_cpu(*z1r) - le16_to_cpu(*z2r); |
536 | if (!fcnt) | 554 | if (!fcnt) |
537 | return 0; /* no data avail */ | 555 | return; /* no data avail */ |
538 | 556 | ||
539 | if (fcnt <= 0) | 557 | if (fcnt <= 0) |
540 | fcnt += B_FIFO_SIZE; /* bytes actually buffered */ | 558 | fcnt += B_FIFO_SIZE; /* bytes actually buffered */ |
541 | if (fcnt > HFCPCI_BTRANS_THRESHOLD) | ||
542 | fcnt = HFCPCI_BTRANS_THRESHOLD; /* limit size */ | ||
543 | |||
544 | new_z2 = le16_to_cpu(*z2r) + fcnt; /* new position in fifo */ | 559 | new_z2 = le16_to_cpu(*z2r) + fcnt; /* new position in fifo */ |
545 | if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) | 560 | if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) |
546 | new_z2 -= B_FIFO_SIZE; /* buffer wrap */ | 561 | new_z2 -= B_FIFO_SIZE; /* buffer wrap */ |
547 | 562 | ||
563 | if (fcnt > MAX_DATA_SIZE) { /* flush, if oversized */ | ||
564 | *z2r = cpu_to_le16(new_z2); /* new position */ | ||
565 | return; | ||
566 | } | ||
567 | |||
548 | bch->rx_skb = mI_alloc_skb(fcnt, GFP_ATOMIC); | 568 | bch->rx_skb = mI_alloc_skb(fcnt, GFP_ATOMIC); |
549 | if (bch->rx_skb) { | 569 | if (bch->rx_skb) { |
550 | ptr = skb_put(bch->rx_skb, fcnt); | 570 | ptr = skb_put(bch->rx_skb, fcnt); |
@@ -569,7 +589,6 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata) | |||
569 | printk(KERN_WARNING "HFCPCI: receive out of memory\n"); | 589 | printk(KERN_WARNING "HFCPCI: receive out of memory\n"); |
570 | 590 | ||
571 | *z2r = cpu_to_le16(new_z2); /* new position */ | 591 | *z2r = cpu_to_le16(new_z2); /* new position */ |
572 | return 1; | ||
573 | } | 592 | } |
574 | 593 | ||
575 | /* | 594 | /* |
@@ -580,12 +599,11 @@ main_rec_hfcpci(struct bchannel *bch) | |||
580 | { | 599 | { |
581 | struct hfc_pci *hc = bch->hw; | 600 | struct hfc_pci *hc = bch->hw; |
582 | int rcnt, real_fifo; | 601 | int rcnt, real_fifo; |
583 | int receive, count = 5; | 602 | int receive = 0, count = 5; |
584 | struct bzfifo *bz; | 603 | struct bzfifo *bz; |
585 | u_char *bdata; | 604 | u_char *bdata; |
586 | struct zt *zp; | 605 | struct zt *zp; |
587 | 606 | ||
588 | |||
589 | if ((bch->nr & 2) && (!hc->hw.bswapped)) { | 607 | if ((bch->nr & 2) && (!hc->hw.bswapped)) { |
590 | bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2; | 608 | bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2; |
591 | bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2; | 609 | bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2; |
@@ -625,9 +643,10 @@ Begin: | |||
625 | receive = 1; | 643 | receive = 1; |
626 | else | 644 | else |
627 | receive = 0; | 645 | receive = 0; |
628 | } else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) | 646 | } else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { |
629 | receive = hfcpci_empty_fifo_trans(bch, bz, bdata); | 647 | hfcpci_empty_fifo_trans(bch, bz, bdata); |
630 | else | 648 | return; |
649 | } else | ||
631 | receive = 0; | 650 | receive = 0; |
632 | if (count && receive) | 651 | if (count && receive) |
633 | goto Begin; | 652 | goto Begin; |
@@ -751,11 +770,41 @@ hfcpci_fill_fifo(struct bchannel *bch) | |||
751 | /* fcnt contains available bytes in fifo */ | 770 | /* fcnt contains available bytes in fifo */ |
752 | fcnt = B_FIFO_SIZE - fcnt; | 771 | fcnt = B_FIFO_SIZE - fcnt; |
753 | /* remaining bytes to send (bytes in fifo) */ | 772 | /* remaining bytes to send (bytes in fifo) */ |
773 | |||
774 | /* "fill fifo if empty" feature */ | ||
775 | if (test_bit(FLG_FILLEMPTY, &bch->Flags) && !fcnt) { | ||
776 | /* printk(KERN_DEBUG "%s: buffer empty, so we have " | ||
777 | "underrun\n", __func__); */ | ||
778 | /* fill buffer, to prevent future underrun */ | ||
779 | count = HFCPCI_FILLEMPTY; | ||
780 | new_z1 = le16_to_cpu(*z1t) + count; | ||
781 | /* new buffer Position */ | ||
782 | if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) | ||
783 | new_z1 -= B_FIFO_SIZE; /* buffer wrap */ | ||
784 | dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL); | ||
785 | maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t); | ||
786 | /* end of fifo */ | ||
787 | if (bch->debug & DEBUG_HW_BFIFO) | ||
788 | printk(KERN_DEBUG "hfcpci_FFt fillempty " | ||
789 | "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n", | ||
790 | fcnt, maxlen, new_z1, dst); | ||
791 | fcnt += count; | ||
792 | if (maxlen > count) | ||
793 | maxlen = count; /* limit size */ | ||
794 | memset(dst, 0x2a, maxlen); /* first copy */ | ||
795 | count -= maxlen; /* remaining bytes */ | ||
796 | if (count) { | ||
797 | dst = bdata; /* start of buffer */ | ||
798 | memset(dst, 0x2a, count); | ||
799 | } | ||
800 | *z1t = cpu_to_le16(new_z1); /* now send data */ | ||
801 | } | ||
802 | |||
754 | next_t_frame: | 803 | next_t_frame: |
755 | count = bch->tx_skb->len - bch->tx_idx; | 804 | count = bch->tx_skb->len - bch->tx_idx; |
756 | /* maximum fill shall be HFCPCI_BTRANS_MAX */ | 805 | /* maximum fill shall be poll*2 */ |
757 | if (count > HFCPCI_BTRANS_MAX - fcnt) | 806 | if (count > (poll << 1) - fcnt) |
758 | count = HFCPCI_BTRANS_MAX - fcnt; | 807 | count = (poll << 1) - fcnt; |
759 | if (count <= 0) | 808 | if (count <= 0) |
760 | return; | 809 | return; |
761 | /* data is suitable for fifo */ | 810 | /* data is suitable for fifo */ |
@@ -1135,37 +1184,37 @@ hfcpci_int(int intno, void *dev_id) | |||
1135 | val &= ~0x80; | 1184 | val &= ~0x80; |
1136 | Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | HFCPCI_CLTIMER); | 1185 | Write_hfc(hc, HFCPCI_CTMT, hc->hw.ctmt | HFCPCI_CLTIMER); |
1137 | } | 1186 | } |
1138 | if (val & 0x08) { | 1187 | if (val & 0x08) { /* B1 rx */ |
1139 | bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); | 1188 | bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); |
1140 | if (bch) | 1189 | if (bch) |
1141 | main_rec_hfcpci(bch); | 1190 | main_rec_hfcpci(bch); |
1142 | else if (hc->dch.debug) | 1191 | else if (hc->dch.debug) |
1143 | printk(KERN_DEBUG "hfcpci spurious 0x08 IRQ\n"); | 1192 | printk(KERN_DEBUG "hfcpci spurious 0x08 IRQ\n"); |
1144 | } | 1193 | } |
1145 | if (val & 0x10) { | 1194 | if (val & 0x10) { /* B2 rx */ |
1146 | bch = Sel_BCS(hc, 2); | 1195 | bch = Sel_BCS(hc, 2); |
1147 | if (bch) | 1196 | if (bch) |
1148 | main_rec_hfcpci(bch); | 1197 | main_rec_hfcpci(bch); |
1149 | else if (hc->dch.debug) | 1198 | else if (hc->dch.debug) |
1150 | printk(KERN_DEBUG "hfcpci spurious 0x10 IRQ\n"); | 1199 | printk(KERN_DEBUG "hfcpci spurious 0x10 IRQ\n"); |
1151 | } | 1200 | } |
1152 | if (val & 0x01) { | 1201 | if (val & 0x01) { /* B1 tx */ |
1153 | bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); | 1202 | bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); |
1154 | if (bch) | 1203 | if (bch) |
1155 | tx_birq(bch); | 1204 | tx_birq(bch); |
1156 | else if (hc->dch.debug) | 1205 | else if (hc->dch.debug) |
1157 | printk(KERN_DEBUG "hfcpci spurious 0x01 IRQ\n"); | 1206 | printk(KERN_DEBUG "hfcpci spurious 0x01 IRQ\n"); |
1158 | } | 1207 | } |
1159 | if (val & 0x02) { | 1208 | if (val & 0x02) { /* B2 tx */ |
1160 | bch = Sel_BCS(hc, 2); | 1209 | bch = Sel_BCS(hc, 2); |
1161 | if (bch) | 1210 | if (bch) |
1162 | tx_birq(bch); | 1211 | tx_birq(bch); |
1163 | else if (hc->dch.debug) | 1212 | else if (hc->dch.debug) |
1164 | printk(KERN_DEBUG "hfcpci spurious 0x02 IRQ\n"); | 1213 | printk(KERN_DEBUG "hfcpci spurious 0x02 IRQ\n"); |
1165 | } | 1214 | } |
1166 | if (val & 0x20) | 1215 | if (val & 0x20) /* D rx */ |
1167 | receive_dmsg(hc); | 1216 | receive_dmsg(hc); |
1168 | if (val & 0x04) { /* dframe transmitted */ | 1217 | if (val & 0x04) { /* D tx */ |
1169 | if (test_and_clear_bit(FLG_BUSY_TIMER, &hc->dch.Flags)) | 1218 | if (test_and_clear_bit(FLG_BUSY_TIMER, &hc->dch.Flags)) |
1170 | del_timer(&hc->dch.timer); | 1219 | del_timer(&hc->dch.timer); |
1171 | tx_dirq(&hc->dch); | 1220 | tx_dirq(&hc->dch); |
@@ -1283,14 +1332,16 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol) | |||
1283 | } | 1332 | } |
1284 | if (fifo2 & 2) { | 1333 | if (fifo2 & 2) { |
1285 | hc->hw.fifo_en |= HFCPCI_FIFOEN_B2; | 1334 | hc->hw.fifo_en |= HFCPCI_FIFOEN_B2; |
1286 | hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS + | 1335 | if (!tics) |
1287 | HFCPCI_INTS_B2REC); | 1336 | hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS + |
1337 | HFCPCI_INTS_B2REC); | ||
1288 | hc->hw.ctmt |= 2; | 1338 | hc->hw.ctmt |= 2; |
1289 | hc->hw.conn &= ~0x18; | 1339 | hc->hw.conn &= ~0x18; |
1290 | } else { | 1340 | } else { |
1291 | hc->hw.fifo_en |= HFCPCI_FIFOEN_B1; | 1341 | hc->hw.fifo_en |= HFCPCI_FIFOEN_B1; |
1292 | hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS + | 1342 | if (!tics) |
1293 | HFCPCI_INTS_B1REC); | 1343 | hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS + |
1344 | HFCPCI_INTS_B1REC); | ||
1294 | hc->hw.ctmt |= 1; | 1345 | hc->hw.ctmt |= 1; |
1295 | hc->hw.conn &= ~0x03; | 1346 | hc->hw.conn &= ~0x03; |
1296 | } | 1347 | } |
@@ -1398,7 +1449,8 @@ set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan) | |||
1398 | if (chan & 2) { | 1449 | if (chan & 2) { |
1399 | hc->hw.sctrl_r |= SCTRL_B2_ENA; | 1450 | hc->hw.sctrl_r |= SCTRL_B2_ENA; |
1400 | hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX; | 1451 | hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX; |
1401 | hc->hw.int_m1 |= HFCPCI_INTS_B2REC; | 1452 | if (!tics) |
1453 | hc->hw.int_m1 |= HFCPCI_INTS_B2REC; | ||
1402 | hc->hw.ctmt |= 2; | 1454 | hc->hw.ctmt |= 2; |
1403 | hc->hw.conn &= ~0x18; | 1455 | hc->hw.conn &= ~0x18; |
1404 | #ifdef REVERSE_BITORDER | 1456 | #ifdef REVERSE_BITORDER |
@@ -1407,7 +1459,8 @@ set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan) | |||
1407 | } else { | 1459 | } else { |
1408 | hc->hw.sctrl_r |= SCTRL_B1_ENA; | 1460 | hc->hw.sctrl_r |= SCTRL_B1_ENA; |
1409 | hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX; | 1461 | hc->hw.fifo_en |= HFCPCI_FIFOEN_B1RX; |
1410 | hc->hw.int_m1 |= HFCPCI_INTS_B1REC; | 1462 | if (!tics) |
1463 | hc->hw.int_m1 |= HFCPCI_INTS_B1REC; | ||
1411 | hc->hw.ctmt |= 1; | 1464 | hc->hw.ctmt |= 1; |
1412 | hc->hw.conn &= ~0x03; | 1465 | hc->hw.conn &= ~0x03; |
1413 | #ifdef REVERSE_BITORDER | 1466 | #ifdef REVERSE_BITORDER |
@@ -1481,11 +1534,17 @@ deactivate_bchannel(struct bchannel *bch) | |||
1481 | static int | 1534 | static int |
1482 | channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) | 1535 | channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) |
1483 | { | 1536 | { |
1484 | int ret = 0; | 1537 | int ret = 0; |
1485 | 1538 | ||
1486 | switch (cq->op) { | 1539 | switch (cq->op) { |
1487 | case MISDN_CTRL_GETOP: | 1540 | case MISDN_CTRL_GETOP: |
1488 | cq->op = 0; | 1541 | cq->op = MISDN_CTRL_FILL_EMPTY; |
1542 | break; | ||
1543 | case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */ | ||
1544 | test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); | ||
1545 | if (debug & DEBUG_HW_OPEN) | ||
1546 | printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d " | ||
1547 | "off=%d)\n", __func__, bch->nr, !!cq->p1); | ||
1489 | break; | 1548 | break; |
1490 | default: | 1549 | default: |
1491 | printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); | 1550 | printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); |
@@ -1859,6 +1918,10 @@ open_dchannel(struct hfc_pci *hc, struct mISDNchannel *ch, | |||
1859 | hc->dch.dev.id, __builtin_return_address(0)); | 1918 | hc->dch.dev.id, __builtin_return_address(0)); |
1860 | if (rq->protocol == ISDN_P_NONE) | 1919 | if (rq->protocol == ISDN_P_NONE) |
1861 | return -EINVAL; | 1920 | return -EINVAL; |
1921 | if (rq->adr.channel == 1) { | ||
1922 | /* TODO: E-Channel */ | ||
1923 | return -EINVAL; | ||
1924 | } | ||
1862 | if (!hc->initdone) { | 1925 | if (!hc->initdone) { |
1863 | if (rq->protocol == ISDN_P_TE_S0) { | 1926 | if (rq->protocol == ISDN_P_TE_S0) { |
1864 | err = create_l1(&hc->dch, hfc_l1callback); | 1927 | err = create_l1(&hc->dch, hfc_l1callback); |
@@ -1874,6 +1937,11 @@ open_dchannel(struct hfc_pci *hc, struct mISDNchannel *ch, | |||
1874 | if (rq->protocol != ch->protocol) { | 1937 | if (rq->protocol != ch->protocol) { |
1875 | if (hc->hw.protocol == ISDN_P_TE_S0) | 1938 | if (hc->hw.protocol == ISDN_P_TE_S0) |
1876 | l1_event(hc->dch.l1, CLOSE_CHANNEL); | 1939 | l1_event(hc->dch.l1, CLOSE_CHANNEL); |
1940 | if (rq->protocol == ISDN_P_TE_S0) { | ||
1941 | err = create_l1(&hc->dch, hfc_l1callback); | ||
1942 | if (err) | ||
1943 | return err; | ||
1944 | } | ||
1877 | hc->hw.protocol = rq->protocol; | 1945 | hc->hw.protocol = rq->protocol; |
1878 | ch->protocol = rq->protocol; | 1946 | ch->protocol = rq->protocol; |
1879 | hfcpci_setmode(hc); | 1947 | hfcpci_setmode(hc); |
@@ -1903,6 +1971,7 @@ open_bchannel(struct hfc_pci *hc, struct channel_req *rq) | |||
1903 | bch = &hc->bch[rq->adr.channel - 1]; | 1971 | bch = &hc->bch[rq->adr.channel - 1]; |
1904 | if (test_and_set_bit(FLG_OPEN, &bch->Flags)) | 1972 | if (test_and_set_bit(FLG_OPEN, &bch->Flags)) |
1905 | return -EBUSY; /* b-channel can be only open once */ | 1973 | return -EBUSY; /* b-channel can be only open once */ |
1974 | test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); | ||
1906 | bch->ch.protocol = rq->protocol; | 1975 | bch->ch.protocol = rq->protocol; |
1907 | rq->ch = &bch->ch; /* TODO: E-channel */ | 1976 | rq->ch = &bch->ch; /* TODO: E-channel */ |
1908 | if (!try_module_get(THIS_MODULE)) | 1977 | if (!try_module_get(THIS_MODULE)) |
@@ -1928,7 +1997,8 @@ hfc_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) | |||
1928 | switch (cmd) { | 1997 | switch (cmd) { |
1929 | case OPEN_CHANNEL: | 1998 | case OPEN_CHANNEL: |
1930 | rq = arg; | 1999 | rq = arg; |
1931 | if (rq->adr.channel == 0) | 2000 | if ((rq->protocol == ISDN_P_TE_S0) || |
2001 | (rq->protocol == ISDN_P_NT_S0)) | ||
1932 | err = open_dchannel(hc, ch, rq); | 2002 | err = open_dchannel(hc, ch, rq); |
1933 | else | 2003 | else |
1934 | err = open_bchannel(hc, rq); | 2004 | err = open_bchannel(hc, rq); |
@@ -2027,7 +2097,6 @@ release_card(struct hfc_pci *hc) { | |||
2027 | mISDN_freebchannel(&hc->bch[1]); | 2097 | mISDN_freebchannel(&hc->bch[1]); |
2028 | mISDN_freebchannel(&hc->bch[0]); | 2098 | mISDN_freebchannel(&hc->bch[0]); |
2029 | mISDN_freedchannel(&hc->dch); | 2099 | mISDN_freedchannel(&hc->dch); |
2030 | list_del(&hc->list); | ||
2031 | pci_set_drvdata(hc->pdev, NULL); | 2100 | pci_set_drvdata(hc->pdev, NULL); |
2032 | kfree(hc); | 2101 | kfree(hc); |
2033 | } | 2102 | } |
@@ -2037,12 +2106,8 @@ setup_card(struct hfc_pci *card) | |||
2037 | { | 2106 | { |
2038 | int err = -EINVAL; | 2107 | int err = -EINVAL; |
2039 | u_int i; | 2108 | u_int i; |
2040 | u_long flags; | ||
2041 | char name[MISDN_MAX_IDLEN]; | 2109 | char name[MISDN_MAX_IDLEN]; |
2042 | 2110 | ||
2043 | if (HFC_cnt >= MAX_CARDS) | ||
2044 | return -EINVAL; /* maybe better value */ | ||
2045 | |||
2046 | card->dch.debug = debug; | 2111 | card->dch.debug = debug; |
2047 | spin_lock_init(&card->lock); | 2112 | spin_lock_init(&card->lock); |
2048 | mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, ph_state); | 2113 | mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, ph_state); |
@@ -2068,13 +2133,10 @@ setup_card(struct hfc_pci *card) | |||
2068 | if (err) | 2133 | if (err) |
2069 | goto error; | 2134 | goto error; |
2070 | snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-pci.%d", HFC_cnt + 1); | 2135 | snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-pci.%d", HFC_cnt + 1); |
2071 | err = mISDN_register_device(&card->dch.dev, name); | 2136 | err = mISDN_register_device(&card->dch.dev, &card->pdev->dev, name); |
2072 | if (err) | 2137 | if (err) |
2073 | goto error; | 2138 | goto error; |
2074 | HFC_cnt++; | 2139 | HFC_cnt++; |
2075 | write_lock_irqsave(&HFClock, flags); | ||
2076 | list_add_tail(&card->list, &HFClist); | ||
2077 | write_unlock_irqrestore(&HFClock, flags); | ||
2078 | printk(KERN_INFO "HFC %d cards installed\n", HFC_cnt); | 2140 | printk(KERN_INFO "HFC %d cards installed\n", HFC_cnt); |
2079 | return 0; | 2141 | return 0; |
2080 | error: | 2142 | error: |
@@ -2210,15 +2272,12 @@ static void __devexit | |||
2210 | hfc_remove_pci(struct pci_dev *pdev) | 2272 | hfc_remove_pci(struct pci_dev *pdev) |
2211 | { | 2273 | { |
2212 | struct hfc_pci *card = pci_get_drvdata(pdev); | 2274 | struct hfc_pci *card = pci_get_drvdata(pdev); |
2213 | u_long flags; | ||
2214 | 2275 | ||
2215 | if (card) { | 2276 | if (card) |
2216 | write_lock_irqsave(&HFClock, flags); | ||
2217 | release_card(card); | 2277 | release_card(card); |
2218 | write_unlock_irqrestore(&HFClock, flags); | 2278 | else |
2219 | } else | ||
2220 | if (debug) | 2279 | if (debug) |
2221 | printk(KERN_WARNING "%s: drvdata allready removed\n", | 2280 | printk(KERN_WARNING "%s: drvdata already removed\n", |
2222 | __func__); | 2281 | __func__); |
2223 | } | 2282 | } |
2224 | 2283 | ||
@@ -2230,25 +2289,97 @@ static struct pci_driver hfc_driver = { | |||
2230 | .id_table = hfc_ids, | 2289 | .id_table = hfc_ids, |
2231 | }; | 2290 | }; |
2232 | 2291 | ||
2292 | static int | ||
2293 | _hfcpci_softirq(struct device *dev, void *arg) | ||
2294 | { | ||
2295 | struct hfc_pci *hc = dev_get_drvdata(dev); | ||
2296 | struct bchannel *bch; | ||
2297 | if (hc == NULL) | ||
2298 | return 0; | ||
2299 | |||
2300 | if (hc->hw.int_m2 & HFCPCI_IRQ_ENABLE) { | ||
2301 | spin_lock(&hc->lock); | ||
2302 | bch = Sel_BCS(hc, hc->hw.bswapped ? 2 : 1); | ||
2303 | if (bch && bch->state == ISDN_P_B_RAW) { /* B1 rx&tx */ | ||
2304 | main_rec_hfcpci(bch); | ||
2305 | tx_birq(bch); | ||
2306 | } | ||
2307 | bch = Sel_BCS(hc, hc->hw.bswapped ? 1 : 2); | ||
2308 | if (bch && bch->state == ISDN_P_B_RAW) { /* B2 rx&tx */ | ||
2309 | main_rec_hfcpci(bch); | ||
2310 | tx_birq(bch); | ||
2311 | } | ||
2312 | spin_unlock(&hc->lock); | ||
2313 | } | ||
2314 | return 0; | ||
2315 | } | ||
2316 | |||
2317 | static void | ||
2318 | hfcpci_softirq(void *arg) | ||
2319 | { | ||
2320 | (void) driver_for_each_device(&hfc_driver.driver, NULL, arg, | ||
2321 | _hfcpci_softirq); | ||
2322 | |||
2323 | /* if next event would be in the past ... */ | ||
2324 | if ((s32)(hfc_jiffies + tics - jiffies) <= 0) | ||
2325 | hfc_jiffies = jiffies + 1; | ||
2326 | else | ||
2327 | hfc_jiffies += tics; | ||
2328 | hfc_tl.expires = hfc_jiffies; | ||
2329 | add_timer(&hfc_tl); | ||
2330 | } | ||
2331 | |||
2233 | static int __init | 2332 | static int __init |
2234 | HFC_init(void) | 2333 | HFC_init(void) |
2235 | { | 2334 | { |
2236 | int err; | 2335 | int err; |
2237 | 2336 | ||
2337 | if (!poll) | ||
2338 | poll = HFCPCI_BTRANS_THRESHOLD; | ||
2339 | |||
2340 | if (poll != HFCPCI_BTRANS_THRESHOLD) { | ||
2341 | tics = (poll * HZ) / 8000; | ||
2342 | if (tics < 1) | ||
2343 | tics = 1; | ||
2344 | poll = (tics * 8000) / HZ; | ||
2345 | if (poll > 256 || poll < 8) { | ||
2346 | printk(KERN_ERR "%s: Wrong poll value %d not in range " | ||
2347 | "of 8..256.\n", __func__, poll); | ||
2348 | err = -EINVAL; | ||
2349 | return err; | ||
2350 | } | ||
2351 | } | ||
2352 | if (poll != HFCPCI_BTRANS_THRESHOLD) { | ||
2353 | printk(KERN_INFO "%s: Using alternative poll value of %d\n", | ||
2354 | __func__, poll); | ||
2355 | hfc_tl.function = (void *)hfcpci_softirq; | ||
2356 | hfc_tl.data = 0; | ||
2357 | init_timer(&hfc_tl); | ||
2358 | hfc_tl.expires = jiffies + tics; | ||
2359 | hfc_jiffies = hfc_tl.expires; | ||
2360 | add_timer(&hfc_tl); | ||
2361 | } else | ||
2362 | tics = 0; /* indicate the use of controller's timer */ | ||
2363 | |||
2238 | err = pci_register_driver(&hfc_driver); | 2364 | err = pci_register_driver(&hfc_driver); |
2365 | if (err) { | ||
2366 | if (timer_pending(&hfc_tl)) | ||
2367 | del_timer(&hfc_tl); | ||
2368 | } | ||
2369 | |||
2239 | return err; | 2370 | return err; |
2240 | } | 2371 | } |
2241 | 2372 | ||
2242 | static void __exit | 2373 | static void __exit |
2243 | HFC_cleanup(void) | 2374 | HFC_cleanup(void) |
2244 | { | 2375 | { |
2245 | struct hfc_pci *card, *next; | 2376 | if (timer_pending(&hfc_tl)) |
2377 | del_timer(&hfc_tl); | ||
2246 | 2378 | ||
2247 | list_for_each_entry_safe(card, next, &HFClist, list) { | ||
2248 | release_card(card); | ||
2249 | } | ||
2250 | pci_unregister_driver(&hfc_driver); | 2379 | pci_unregister_driver(&hfc_driver); |
2251 | } | 2380 | } |
2252 | 2381 | ||
2253 | module_init(HFC_init); | 2382 | module_init(HFC_init); |
2254 | module_exit(HFC_cleanup); | 2383 | module_exit(HFC_cleanup); |
2384 | |||
2385 | MODULE_DEVICE_TABLE(pci, hfc_ids); | ||