diff options
Diffstat (limited to 'drivers/isdn/hardware/mISDN/mISDNipac.c')
-rw-r--r-- | drivers/isdn/hardware/mISDN/mISDNipac.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c index 3e71a5ef4bbc..374a17751ffb 100644 --- a/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c | |||
@@ -969,22 +969,28 @@ hscx_fill_fifo(struct hscx_hw *hscx) | |||
969 | int count, more; | 969 | int count, more; |
970 | u8 *p; | 970 | u8 *p; |
971 | 971 | ||
972 | if (!hscx->bch.tx_skb) | 972 | if (!hscx->bch.tx_skb) { |
973 | return; | 973 | if (!test_bit(FLG_TX_EMPTY, &hscx->bch.Flags)) |
974 | count = hscx->bch.tx_skb->len - hscx->bch.tx_idx; | 974 | return; |
975 | if (count <= 0) | ||
976 | return; | ||
977 | p = hscx->bch.tx_skb->data + hscx->bch.tx_idx; | ||
978 | |||
979 | more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0; | ||
980 | if (count > hscx->fifo_size) { | ||
981 | count = hscx->fifo_size; | 975 | count = hscx->fifo_size; |
982 | more = 1; | 976 | more = 1; |
983 | } | 977 | p = hscx->log; |
984 | pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr, count, | 978 | memset(p, hscx->bch.fill[0], count); |
985 | hscx->bch.tx_idx, hscx->bch.tx_skb->len); | 979 | } else { |
986 | hscx->bch.tx_idx += count; | 980 | count = hscx->bch.tx_skb->len - hscx->bch.tx_idx; |
981 | if (count <= 0) | ||
982 | return; | ||
983 | p = hscx->bch.tx_skb->data + hscx->bch.tx_idx; | ||
987 | 984 | ||
985 | more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0; | ||
986 | if (count > hscx->fifo_size) { | ||
987 | count = hscx->fifo_size; | ||
988 | more = 1; | ||
989 | } | ||
990 | pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr, | ||
991 | count, hscx->bch.tx_idx, hscx->bch.tx_skb->len); | ||
992 | hscx->bch.tx_idx += count; | ||
993 | } | ||
988 | if (hscx->ip->type & IPAC_TYPE_IPACX) | 994 | if (hscx->ip->type & IPAC_TYPE_IPACX) |
989 | hscx->ip->write_fifo(hscx->ip->hw, | 995 | hscx->ip->write_fifo(hscx->ip->hw, |
990 | hscx->off + IPACX_XFIFOB, p, count); | 996 | hscx->off + IPACX_XFIFOB, p, count); |
@@ -995,7 +1001,7 @@ hscx_fill_fifo(struct hscx_hw *hscx) | |||
995 | } | 1001 | } |
996 | hscx_cmdr(hscx, more ? 0x08 : 0x0a); | 1002 | hscx_cmdr(hscx, more ? 0x08 : 0x0a); |
997 | 1003 | ||
998 | if (hscx->bch.debug & DEBUG_HW_BFIFO) { | 1004 | if (hscx->bch.tx_skb && (hscx->bch.debug & DEBUG_HW_BFIFO)) { |
999 | snprintf(hscx->log, 64, "B%1d-send %s %d ", | 1005 | snprintf(hscx->log, 64, "B%1d-send %s %d ", |
1000 | hscx->bch.nr, hscx->ip->name, count); | 1006 | hscx->bch.nr, hscx->ip->name, count); |
1001 | print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count); | 1007 | print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count); |
@@ -1010,8 +1016,12 @@ hscx_xpr(struct hscx_hw *hx) | |||
1010 | } else { | 1016 | } else { |
1011 | if (hx->bch.tx_skb) | 1017 | if (hx->bch.tx_skb) |
1012 | dev_kfree_skb(hx->bch.tx_skb); | 1018 | dev_kfree_skb(hx->bch.tx_skb); |
1013 | if (get_next_bframe(&hx->bch)) | 1019 | if (get_next_bframe(&hx->bch)) { |
1014 | hscx_fill_fifo(hx); | 1020 | hscx_fill_fifo(hx); |
1021 | test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags); | ||
1022 | } else if (test_bit(FLG_TX_EMPTY, &hx->bch.Flags)) { | ||
1023 | hscx_fill_fifo(hx); | ||
1024 | } | ||
1015 | } | 1025 | } |
1016 | } | 1026 | } |
1017 | 1027 | ||
@@ -1128,7 +1138,9 @@ ipac_irq(struct hscx_hw *hx, u8 ista) | |||
1128 | 1138 | ||
1129 | if (istab & IPACX_B_XDU) { | 1139 | if (istab & IPACX_B_XDU) { |
1130 | if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) { | 1140 | if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) { |
1131 | hscx_fill_fifo(hx); | 1141 | if (test_bit(FLG_FILLEMPTY, &hx->bch.Flags)) |
1142 | test_and_set_bit(FLG_TX_EMPTY, &hx->bch.Flags); | ||
1143 | hscx_xpr(hx); | ||
1132 | return; | 1144 | return; |
1133 | } | 1145 | } |
1134 | pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name, | 1146 | pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name, |