|
@@ -180,7 +180,6 @@ static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 };
|
|
|
#define CLKDEL_TE 0x0f /* CLKDEL in TE mode */
|
|
|
#define CLKDEL_NT 0x6c /* CLKDEL in NT mode
|
|
|
(0x60 MUST be included!) */
|
|
|
-static u_char silence = 0xff; /* silence by LAW */
|
|
|
|
|
|
#define DIP_4S 0x1 /* DIP Switches for Beronet 1S/2S/4S cards */
|
|
|
#define DIP_8S 0x2 /* DIP Switches for Beronet 8S+ cards */
|
|
@@ -1975,6 +1974,17 @@ next_frame:
|
|
|
return; /* no data */
|
|
|
}
|
|
|
|
|
|
+ /* "fill fifo if empty" feature */
|
|
|
+ if (bch && test_bit(FLG_FILLEMPTY, &bch->Flags)
|
|
|
+ && !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) {
|
|
|
+ if (debug & DEBUG_HFCMULTI_FILL)
|
|
|
+ printk(KERN_DEBUG "%s: buffer empty, so we have "
|
|
|
+ "underrun\n", __func__);
|
|
|
+ /* fill buffer, to prevent future underrun */
|
|
|
+ hc->write_fifo(hc, hc->silence_data, poll >> 1);
|
|
|
+ Zspace -= (poll >> 1);
|
|
|
+ }
|
|
|
+
|
|
|
/* if audio data and connected slot */
|
|
|
if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending)
|
|
|
&& slot_tx >= 0) {
|
|
@@ -2011,7 +2021,6 @@ next_frame:
|
|
|
__func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,
|
|
|
temp ? "HDLC":"TRANS");
|
|
|
|
|
|
-
|
|
|
/* Have to prep the audio data */
|
|
|
hc->write_fifo(hc, d, ii - i);
|
|
|
*idxp = ii;
|
|
@@ -2050,7 +2059,7 @@ next_frame:
|
|
|
* no more data at all. this prevents sending an undefined value.
|
|
|
*/
|
|
|
if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags))
|
|
|
- HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence);
|
|
|
+ HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2932,7 +2941,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
|
|
|
HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
|
|
|
HFC_wait(hc);
|
|
|
/* tx silence */
|
|
|
- HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence);
|
|
|
+ HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
|
|
|
HFC_outb(hc, R_SLOT, (((ch / 4) * 8) +
|
|
|
((ch % 4) * 4)) << 1);
|
|
|
HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1));
|
|
@@ -2947,7 +2956,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
|
|
|
HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
|
|
|
HFC_wait(hc);
|
|
|
/* tx silence */
|
|
|
- HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, silence);
|
|
|
+ HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence);
|
|
|
/* enable RX fifo */
|
|
|
HFC_outb(hc, R_FIFO, (ch<<1)|1);
|
|
|
HFC_wait(hc);
|
|
@@ -3439,7 +3448,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
|
|
|
switch (cq->op) {
|
|
|
case MISDN_CTRL_GETOP:
|
|
|
cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP
|
|
|
- | MISDN_CTRL_RX_OFF;
|
|
|
+ | MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY;
|
|
|
break;
|
|
|
case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
|
|
|
hc->chan[bch->slot].rx_off = !!cq->p1;
|
|
@@ -3454,6 +3463,12 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
|
|
|
printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n",
|
|
|
__func__, bch->nr, hc->chan[bch->slot].rx_off);
|
|
|
break;
|
|
|
+ case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */
|
|
|
+ test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
|
|
|
+ if (debug & DEBUG_HFCMULTI_MSG)
|
|
|
+ printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d "
|
|
|
+ "off=%d)\n", __func__, bch->nr, !!cq->p1);
|
|
|
+ break;
|
|
|
case MISDN_CTRL_HW_FEATURES: /* fill features structure */
|
|
|
if (debug & DEBUG_HFCMULTI_MSG)
|
|
|
printk(KERN_DEBUG "%s: HW_FEATURE request\n",
|
|
@@ -3970,6 +3985,7 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
|
|
|
}
|
|
|
if (test_and_set_bit(FLG_OPEN, &bch->Flags))
|
|
|
return -EBUSY; /* b-channel can be only open once */
|
|
|
+ test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
|
|
|
bch->ch.protocol = rq->protocol;
|
|
|
hc->chan[ch].rx_off = 0;
|
|
|
rq->ch = &bch->ch;
|
|
@@ -4806,6 +4822,7 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
struct hfc_multi *hc;
|
|
|
u_long flags;
|
|
|
u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */
|
|
|
+ int i;
|
|
|
|
|
|
if (HFC_cnt >= MAX_CARDS) {
|
|
|
printk(KERN_ERR "too many cards (max=%d).\n",
|
|
@@ -4839,11 +4856,11 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
hc->id = HFC_cnt;
|
|
|
hc->pcm = pcm[HFC_cnt];
|
|
|
hc->io_mode = iomode[HFC_cnt];
|
|
|
- if (dslot[HFC_cnt] < 0) {
|
|
|
+ if (dslot[HFC_cnt] < 0 && hc->type == 1) {
|
|
|
hc->dslot = 0;
|
|
|
printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
|
|
|
"31 B-channels\n");
|
|
|
- } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32) {
|
|
|
+ } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32 && hc->type == 1) {
|
|
|
hc->dslot = dslot[HFC_cnt];
|
|
|
printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
|
|
|
"time slot %d\n", dslot[HFC_cnt]);
|
|
@@ -4854,9 +4871,17 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
hc->masterclk = -1;
|
|
|
if (type[HFC_cnt] & 0x100) {
|
|
|
test_and_set_bit(HFC_CHIP_ULAW, &hc->chip);
|
|
|
- silence = 0xff; /* ulaw silence */
|
|
|
+ hc->silence = 0xff; /* ulaw silence */
|
|
|
} else
|
|
|
- silence = 0x2a; /* alaw silence */
|
|
|
+ hc->silence = 0x2a; /* alaw silence */
|
|
|
+ if ((poll >> 1) > sizeof(hc->silence_data)) {
|
|
|
+ printk(KERN_ERR "HFCMULTI error: silence_data too small, "
|
|
|
+ "please fix\n");
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+ for (i = 0; i < (poll >> 1); i++)
|
|
|
+ hc->silence_data[i] = hc->silence;
|
|
|
+
|
|
|
if (!(type[HFC_cnt] & 0x200))
|
|
|
test_and_set_bit(HFC_CHIP_DTMF, &hc->chip);
|
|
|
|