diff options
Diffstat (limited to 'drivers/isdn/hardware/mISDN/hfcpci.c')
-rw-r--r-- | drivers/isdn/hardware/mISDN/hfcpci.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index cd8302af40eb..80c356e5dbe1 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c | |||
@@ -751,6 +751,36 @@ hfcpci_fill_fifo(struct bchannel *bch) | |||
751 | /* fcnt contains available bytes in fifo */ | 751 | /* fcnt contains available bytes in fifo */ |
752 | fcnt = B_FIFO_SIZE - fcnt; | 752 | fcnt = B_FIFO_SIZE - fcnt; |
753 | /* remaining bytes to send (bytes in fifo) */ | 753 | /* remaining bytes to send (bytes in fifo) */ |
754 | |||
755 | /* "fill fifo if empty" feature */ | ||
756 | if (test_bit(FLG_FILLEMPTY, &bch->Flags) && !fcnt) { | ||
757 | /* printk(KERN_DEBUG "%s: buffer empty, so we have " | ||
758 | "underrun\n", __func__); */ | ||
759 | /* fill buffer, to prevent future underrun */ | ||
760 | count = HFCPCI_FILLEMPTY; | ||
761 | new_z1 = le16_to_cpu(*z1t) + count; | ||
762 | /* new buffer Position */ | ||
763 | if (new_z1 >= (B_FIFO_SIZE + B_SUB_VAL)) | ||
764 | new_z1 -= B_FIFO_SIZE; /* buffer wrap */ | ||
765 | dst = bdata + (le16_to_cpu(*z1t) - B_SUB_VAL); | ||
766 | maxlen = (B_FIFO_SIZE + B_SUB_VAL) - le16_to_cpu(*z1t); | ||
767 | /* end of fifo */ | ||
768 | if (bch->debug & DEBUG_HW_BFIFO) | ||
769 | printk(KERN_DEBUG "hfcpci_FFt fillempty " | ||
770 | "fcnt(%d) maxl(%d) nz1(%x) dst(%p)\n", | ||
771 | fcnt, maxlen, new_z1, dst); | ||
772 | fcnt += count; | ||
773 | if (maxlen > count) | ||
774 | maxlen = count; /* limit size */ | ||
775 | memset(dst, 0x2a, maxlen); /* first copy */ | ||
776 | count -= maxlen; /* remaining bytes */ | ||
777 | if (count) { | ||
778 | dst = bdata; /* start of buffer */ | ||
779 | memset(dst, 0x2a, count); | ||
780 | } | ||
781 | *z1t = cpu_to_le16(new_z1); /* now send data */ | ||
782 | } | ||
783 | |||
754 | next_t_frame: | 784 | next_t_frame: |
755 | count = bch->tx_skb->len - bch->tx_idx; | 785 | count = bch->tx_skb->len - bch->tx_idx; |
756 | /* maximum fill shall be HFCPCI_BTRANS_MAX */ | 786 | /* maximum fill shall be HFCPCI_BTRANS_MAX */ |
@@ -1481,11 +1511,17 @@ deactivate_bchannel(struct bchannel *bch) | |||
1481 | static int | 1511 | static int |
1482 | channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) | 1512 | channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) |
1483 | { | 1513 | { |
1484 | int ret = 0; | 1514 | int ret = 0; |
1485 | 1515 | ||
1486 | switch (cq->op) { | 1516 | switch (cq->op) { |
1487 | case MISDN_CTRL_GETOP: | 1517 | case MISDN_CTRL_GETOP: |
1488 | cq->op = 0; | 1518 | cq->op = MISDN_CTRL_FILL_EMPTY; |
1519 | break; | ||
1520 | case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */ | ||
1521 | test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); | ||
1522 | if (debug & DEBUG_HW_OPEN) | ||
1523 | printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d " | ||
1524 | "off=%d)\n", __func__, bch->nr, !!cq->p1); | ||
1489 | break; | 1525 | break; |
1490 | default: | 1526 | default: |
1491 | printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); | 1527 | printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); |
@@ -1903,6 +1939,7 @@ open_bchannel(struct hfc_pci *hc, struct channel_req *rq) | |||
1903 | bch = &hc->bch[rq->adr.channel - 1]; | 1939 | bch = &hc->bch[rq->adr.channel - 1]; |
1904 | if (test_and_set_bit(FLG_OPEN, &bch->Flags)) | 1940 | if (test_and_set_bit(FLG_OPEN, &bch->Flags)) |
1905 | return -EBUSY; /* b-channel can be only open once */ | 1941 | return -EBUSY; /* b-channel can be only open once */ |
1942 | test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); | ||
1906 | bch->ch.protocol = rq->protocol; | 1943 | bch->ch.protocol = rq->protocol; |
1907 | rq->ch = &bch->ch; /* TODO: E-channel */ | 1944 | rq->ch = &bch->ch; /* TODO: E-channel */ |
1908 | if (!try_module_get(THIS_MODULE)) | 1945 | if (!try_module_get(THIS_MODULE)) |