aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hardware/mISDN/mISDNipac.c
diff options
context:
space:
mode:
authorKarsten Keil <kkeil@linux-pingi.de>2012-05-15 19:51:07 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-16 15:24:05 -0400
commit6d1ee48fd0d8d2586aaeda24dacffc426c2be44a (patch)
tree0a94204bfdf5ac0eb4d03885cb2f87ddb0e8eb1a /drivers/isdn/hardware/mISDN/mISDNipac.c
parent034005a0119b9c2aabe0ac3953eb9a65ca937a69 (diff)
mISDN: Implement MISDN_CTRL_FILL_EMPTY for more drivers
MISDN_CTRL_FILL_EMPTY is a meachanism to send a fixed value (normally silence) as long no data from upper layers is available. It can be used when recording voice messages or with unidirectional protocols. Signed-off-by: Karsten Keil <kkeil@linux-pingi.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn/hardware/mISDN/mISDNipac.c')
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNipac.c44
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,