aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/isdn/hardware/mISDN/avmfritz.c35
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c17
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c12
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.c14
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNipac.c27
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNisar.c25
-rw-r--r--drivers/isdn/hardware/mISDN/netjet.c23
-rw-r--r--drivers/isdn/hardware/mISDN/w6692.c25
-rw-r--r--drivers/isdn/mISDN/hwchannel.c65
-rw-r--r--drivers/isdn/mISDN/l1oip_core.c2
-rw-r--r--include/linux/mISDNhw.h13
-rw-r--r--include/linux/mISDNif.h9
12 files changed, 135 insertions, 132 deletions
diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c
index 808136735f32..7cd3a963ed2e 100644
--- a/drivers/isdn/hardware/mISDN/avmfritz.c
+++ b/drivers/isdn/hardware/mISDN/avmfritz.c
@@ -536,12 +536,12 @@ HDLC_irq(struct bchannel *bch, u32 stat)
536 hdlc_empty_fifo(bch, len); 536 hdlc_empty_fifo(bch, len);
537 if (!bch->rx_skb) 537 if (!bch->rx_skb)
538 goto handle_tx; 538 goto handle_tx;
539 if (test_bit(FLG_TRANSPARENT, &bch->Flags) || 539 if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
540 (stat & HDLC_STAT_RME)) { 540 recv_Bchannel(bch, 0, false);
541 if (((stat & HDLC_STAT_CRCVFRRAB) == 541 } else if (stat & HDLC_STAT_RME) {
542 HDLC_STAT_CRCVFR) || 542 if ((stat & HDLC_STAT_CRCVFRRAB) ==
543 test_bit(FLG_TRANSPARENT, &bch->Flags)) { 543 HDLC_STAT_CRCVFR) {
544 recv_Bchannel(bch, 0); 544 recv_Bchannel(bch, 0, false);
545 } else { 545 } else {
546 pr_warning("%s: got invalid frame\n", 546 pr_warning("%s: got invalid frame\n",
547 fc->name); 547 fc->name);
@@ -809,21 +809,7 @@ init_card(struct fritzcard *fc)
809static int 809static int
810channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) 810channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
811{ 811{
812 int ret = 0; 812 return mISDN_ctrl_bchannel(bch, cq);
813 struct fritzcard *fc = bch->hw;
814
815 switch (cq->op) {
816 case MISDN_CTRL_GETOP:
817 cq->op = 0;
818 break;
819 /* Nothing implemented yet */
820 case MISDN_CTRL_FILL_EMPTY:
821 default:
822 pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op);
823 ret = -EINVAL;
824 break;
825 }
826 return ret;
827} 813}
828 814
829static int 815static int
@@ -1019,6 +1005,7 @@ static int __devinit
1019setup_instance(struct fritzcard *card) 1005setup_instance(struct fritzcard *card)
1020{ 1006{
1021 int i, err; 1007 int i, err;
1008 unsigned short minsize;
1022 u_long flags; 1009 u_long flags;
1023 1010
1024 snprintf(card->name, MISDN_MAX_IDLEN - 1, "AVM.%d", AVM_cnt + 1); 1011 snprintf(card->name, MISDN_MAX_IDLEN - 1, "AVM.%d", AVM_cnt + 1);
@@ -1038,7 +1025,11 @@ setup_instance(struct fritzcard *card)
1038 for (i = 0; i < 2; i++) { 1025 for (i = 0; i < 2; i++) {
1039 card->bch[i].nr = i + 1; 1026 card->bch[i].nr = i + 1;
1040 set_channelmap(i + 1, card->isac.dch.dev.channelmap); 1027 set_channelmap(i + 1, card->isac.dch.dev.channelmap);
1041 mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM); 1028 if (AVM_FRITZ_PCIV2 == card->type)
1029 minsize = HDLC_FIFO_SIZE_V2;
1030 else
1031 minsize = HDLC_FIFO_SIZE_V1;
1032 mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, minsize);
1042 card->bch[i].hw = card; 1033 card->bch[i].hw = card;
1043 card->bch[i].ch.send = avm_l2l1B; 1034 card->bch[i].ch.send = avm_l2l1B;
1044 card->bch[i].ch.ctrl = avm_bctrl; 1035 card->bch[i].ch.ctrl = avm_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 60dd6efa1879..3d4b36d2a31a 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -2352,7 +2352,7 @@ next_frame:
2352 if (dch) 2352 if (dch)
2353 recv_Dchannel(dch); 2353 recv_Dchannel(dch);
2354 else 2354 else
2355 recv_Bchannel(bch, MISDN_ID_ANY); 2355 recv_Bchannel(bch, MISDN_ID_ANY, false);
2356 *sp = skb; 2356 *sp = skb;
2357 again++; 2357 again++;
2358 goto next_frame; 2358 goto next_frame;
@@ -2367,7 +2367,7 @@ next_frame:
2367 "(z1=%04x, z2=%04x) TRANS\n", 2367 "(z1=%04x, z2=%04x) TRANS\n",
2368 __func__, hc->id + 1, ch, Zsize, z1, z2); 2368 __func__, hc->id + 1, ch, Zsize, z1, z2);
2369 /* only bch is transparent */ 2369 /* only bch is transparent */
2370 recv_Bchannel(bch, hc->chan[ch].Zfill); 2370 recv_Bchannel(bch, hc->chan[ch].Zfill, false);
2371 } 2371 }
2372} 2372}
2373 2373
@@ -3574,8 +3574,9 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
3574 3574
3575 switch (cq->op) { 3575 switch (cq->op) {
3576 case MISDN_CTRL_GETOP: 3576 case MISDN_CTRL_GETOP:
3577 cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP 3577 ret = mISDN_ctrl_bchannel(bch, cq);
3578 | MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY; 3578 cq->op |= MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP |
3579 MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY;
3579 break; 3580 break;
3580 case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */ 3581 case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */
3581 hc->chan[bch->slot].rx_off = !!cq->p1; 3582 hc->chan[bch->slot].rx_off = !!cq->p1;
@@ -3683,9 +3684,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
3683 ret = -EINVAL; 3684 ret = -EINVAL;
3684 break; 3685 break;
3685 default: 3686 default:
3686 printk(KERN_WARNING "%s: unknown Op %x\n", 3687 ret = mISDN_ctrl_bchannel(bch, cq);
3687 __func__, cq->op);
3688 ret = -EINVAL;
3689 break; 3688 break;
3690 } 3689 }
3691 return ret; 3690 return ret;
@@ -4855,7 +4854,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
4855 bch->nr = ch; 4854 bch->nr = ch;
4856 bch->slot = ch; 4855 bch->slot = ch;
4857 bch->debug = debug; 4856 bch->debug = debug;
4858 mISDN_initbchannel(bch, MAX_DATA_MEM); 4857 mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1);
4859 bch->hw = hc; 4858 bch->hw = hc;
4860 bch->ch.send = handle_bmsg; 4859 bch->ch.send = handle_bmsg;
4861 bch->ch.ctrl = hfcm_bctrl; 4860 bch->ch.ctrl = hfcm_bctrl;
@@ -4928,7 +4927,7 @@ init_multi_port(struct hfc_multi *hc, int pt)
4928 bch->nr = ch + 1; 4927 bch->nr = ch + 1;
4929 bch->slot = i + ch; 4928 bch->slot = i + ch;
4930 bch->debug = debug; 4929 bch->debug = debug;
4931 mISDN_initbchannel(bch, MAX_DATA_MEM); 4930 mISDN_initbchannel(bch, MAX_DATA_MEM, poll >> 1);
4932 bch->hw = hc; 4931 bch->hw = hc;
4933 bch->ch.send = handle_bmsg; 4932 bch->ch.send = handle_bmsg;
4934 bch->ch.ctrl = hfcm_bctrl; 4933 bch->ch.ctrl = hfcm_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index 0622e05ae066..27743754ab81 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -453,7 +453,7 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
453 } 453 }
454 bz->za[new_f2].z2 = cpu_to_le16(new_z2); 454 bz->za[new_f2].z2 = cpu_to_le16(new_z2);
455 bz->f2 = new_f2; /* next buffer */ 455 bz->f2 = new_f2; /* next buffer */
456 recv_Bchannel(bch, MISDN_ID_ANY); 456 recv_Bchannel(bch, MISDN_ID_ANY, false);
457 } 457 }
458} 458}
459 459
@@ -599,7 +599,7 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz,
599 ptr1 = bdata; /* start of buffer */ 599 ptr1 = bdata; /* start of buffer */
600 memcpy(ptr, ptr1, fcnt_rx); /* rest */ 600 memcpy(ptr, ptr1, fcnt_rx); /* rest */
601 } 601 }
602 recv_Bchannel(bch, fcnt_tx); /* bch, id */ 602 recv_Bchannel(bch, fcnt_tx, false); /* bch, id, !force */
603 } 603 }
604 *z2r = cpu_to_le16(new_z2); /* new position */ 604 *z2r = cpu_to_le16(new_z2); /* new position */
605} 605}
@@ -1535,7 +1535,8 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1535 1535
1536 switch (cq->op) { 1536 switch (cq->op) {
1537 case MISDN_CTRL_GETOP: 1537 case MISDN_CTRL_GETOP:
1538 cq->op = MISDN_CTRL_FILL_EMPTY; 1538 ret = mISDN_ctrl_bchannel(bch, cq);
1539 cq->op |= MISDN_CTRL_FILL_EMPTY;
1539 break; 1540 break;
1540 case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */ 1541 case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */
1541 test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); 1542 test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
@@ -1544,8 +1545,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1544 "off=%d)\n", __func__, bch->nr, !!cq->p1); 1545 "off=%d)\n", __func__, bch->nr, !!cq->p1);
1545 break; 1546 break;
1546 default: 1547 default:
1547 printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); 1548 ret = mISDN_ctrl_bchannel(bch, cq);
1548 ret = -EINVAL;
1549 break; 1549 break;
1550 } 1550 }
1551 return ret; 1551 return ret;
@@ -2116,7 +2116,7 @@ setup_card(struct hfc_pci *card)
2116 card->bch[i].nr = i + 1; 2116 card->bch[i].nr = i + 1;
2117 set_channelmap(i + 1, card->dch.dev.channelmap); 2117 set_channelmap(i + 1, card->dch.dev.channelmap);
2118 card->bch[i].debug = debug; 2118 card->bch[i].debug = debug;
2119 mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM); 2119 mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM, poll >> 1);
2120 card->bch[i].hw = card; 2120 card->bch[i].hw = card;
2121 card->bch[i].ch.send = hfcpci_l2l1B; 2121 card->bch[i].ch.send = hfcpci_l2l1B;
2122 card->bch[i].ch.ctrl = hfc_bctrl; 2122 card->bch[i].ch.ctrl = hfc_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index 6bb689b8d66f..9c17473da83b 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -810,7 +810,8 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
810 810
811 switch (cq->op) { 811 switch (cq->op) {
812 case MISDN_CTRL_GETOP: 812 case MISDN_CTRL_GETOP:
813 cq->op = MISDN_CTRL_FILL_EMPTY; 813 ret = mISDN_ctrl_bchannel(bch, cq);
814 cq->op |= MISDN_CTRL_FILL_EMPTY;
814 break; 815 break;
815 case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */ 816 case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */
816 test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); 817 test_and_set_bit(FLG_FILLEMPTY, &bch->Flags);
@@ -819,8 +820,7 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
819 "off=%d)\n", __func__, bch->nr, !!cq->p1); 820 "off=%d)\n", __func__, bch->nr, !!cq->p1);
820 break; 821 break;
821 default: 822 default:
822 printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); 823 ret = mISDN_ctrl_bchannel(bch, cq);
823 ret = -EINVAL;
824 break; 824 break;
825 } 825 }
826 return ret; 826 return ret;
@@ -931,7 +931,8 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
931 if (fifo->dch) 931 if (fifo->dch)
932 recv_Dchannel(fifo->dch); 932 recv_Dchannel(fifo->dch);
933 if (fifo->bch) 933 if (fifo->bch)
934 recv_Bchannel(fifo->bch, MISDN_ID_ANY); 934 recv_Bchannel(fifo->bch, MISDN_ID_ANY,
935 0);
935 if (fifo->ech) 936 if (fifo->ech)
936 recv_Echannel(fifo->ech, 937 recv_Echannel(fifo->ech,
937 &hw->dch); 938 &hw->dch);
@@ -952,8 +953,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
952 } 953 }
953 } else { 954 } else {
954 /* deliver transparent data to layer2 */ 955 /* deliver transparent data to layer2 */
955 if (rx_skb->len >= poll) 956 recv_Bchannel(fifo->bch, MISDN_ID_ANY, false);
956 recv_Bchannel(fifo->bch, MISDN_ID_ANY);
957 } 957 }
958 spin_unlock(&hw->lock); 958 spin_unlock(&hw->lock);
959} 959}
@@ -1861,7 +1861,7 @@ setup_instance(struct hfcsusb *hw, struct device *parent)
1861 hw->bch[i].nr = i + 1; 1861 hw->bch[i].nr = i + 1;
1862 set_channelmap(i + 1, hw->dch.dev.channelmap); 1862 set_channelmap(i + 1, hw->dch.dev.channelmap);
1863 hw->bch[i].debug = debug; 1863 hw->bch[i].debug = debug;
1864 mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM); 1864 mISDN_initbchannel(&hw->bch[i], MAX_DATA_MEM, poll >> 1);
1865 hw->bch[i].hw = hw; 1865 hw->bch[i].hw = hw;
1866 hw->bch[i].ch.send = hfcusb_l2l1B; 1866 hw->bch[i].ch.send = hfcusb_l2l1B;
1867 hw->bch[i].ch.ctrl = hfc_bctrl; 1867 hw->bch[i].ch.ctrl = hfc_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c
index 7d109ed35366..3e71a5ef4bbc 100644
--- a/drivers/isdn/hardware/mISDN/mISDNipac.c
+++ b/drivers/isdn/hardware/mISDN/mISDNipac.c
@@ -1063,7 +1063,7 @@ ipac_rme(struct hscx_hw *hx)
1063 skb_trim(hx->bch.rx_skb, 0); 1063 skb_trim(hx->bch.rx_skb, 0);
1064 } else { 1064 } else {
1065 skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1); 1065 skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1);
1066 recv_Bchannel(&hx->bch, 0); 1066 recv_Bchannel(&hx->bch, 0, false);
1067 } 1067 }
1068} 1068}
1069 1069
@@ -1114,11 +1114,8 @@ ipac_irq(struct hscx_hw *hx, u8 ista)
1114 1114
1115 if (istab & IPACX_B_RPF) { 1115 if (istab & IPACX_B_RPF) {
1116 hscx_empty_fifo(hx, hx->fifo_size); 1116 hscx_empty_fifo(hx, hx->fifo_size);
1117 if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) { 1117 if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags))
1118 /* receive transparent audio data */ 1118 recv_Bchannel(&hx->bch, 0, false);
1119 if (hx->bch.rx_skb)
1120 recv_Bchannel(&hx->bch, 0);
1121 }
1122 } 1119 }
1123 1120
1124 if (istab & IPACX_B_RFO) { 1121 if (istab & IPACX_B_RFO) {
@@ -1377,20 +1374,7 @@ hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
1377static int 1374static int
1378channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) 1375channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1379{ 1376{
1380 int ret = 0; 1377 return mISDN_ctrl_bchannel(bch, cq);
1381
1382 switch (cq->op) {
1383 case MISDN_CTRL_GETOP:
1384 cq->op = 0;
1385 break;
1386 /* Nothing implemented yet */
1387 case MISDN_CTRL_FILL_EMPTY:
1388 default:
1389 pr_info("%s: unknown Op %x\n", __func__, cq->op);
1390 ret = -EINVAL;
1391 break;
1392 }
1393 return ret;
1394} 1378}
1395 1379
1396static int 1380static int
@@ -1608,7 +1592,8 @@ mISDNipac_init(struct ipac_hw *ipac, void *hw)
1608 set_channelmap(i + 1, ipac->isac.dch.dev.channelmap); 1592 set_channelmap(i + 1, ipac->isac.dch.dev.channelmap);
1609 list_add(&ipac->hscx[i].bch.ch.list, 1593 list_add(&ipac->hscx[i].bch.ch.list,
1610 &ipac->isac.dch.dev.bchannels); 1594 &ipac->isac.dch.dev.bchannels);
1611 mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM); 1595 mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM,
1596 ipac->hscx[i].fifo_size);
1612 ipac->hscx[i].bch.ch.nr = i + 1; 1597 ipac->hscx[i].bch.ch.nr = i + 1;
1613 ipac->hscx[i].bch.ch.send = &hscx_l2l1; 1598 ipac->hscx[i].bch.ch.send = &hscx_l2l1;
1614 ipac->hscx[i].bch.ch.ctrl = hscx_bctrl; 1599 ipac->hscx[i].bch.ch.ctrl = hscx_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c
index 4169bb2db19c..e74ad385e73f 100644
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -446,7 +446,7 @@ isar_rcv_frame(struct isar_ch *ch)
446 break; 446 break;
447 } 447 }
448 rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb)); 448 rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
449 recv_Bchannel(&ch->bch, 0); 449 recv_Bchannel(&ch->bch, 0, false);
450 break; 450 break;
451 case ISDN_P_B_HDLC: 451 case ISDN_P_B_HDLC:
452 maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb); 452 maxlen = bchannel_get_rxbuf(&ch->bch, ch->is->clsb);
@@ -481,7 +481,7 @@ isar_rcv_frame(struct isar_ch *ch)
481 break; 481 break;
482 } 482 }
483 skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2); 483 skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
484 recv_Bchannel(&ch->bch, 0); 484 recv_Bchannel(&ch->bch, 0, false);
485 } 485 }
486 break; 486 break;
487 case ISDN_P_B_T30_FAX: 487 case ISDN_P_B_T30_FAX:
@@ -517,7 +517,7 @@ isar_rcv_frame(struct isar_ch *ch)
517 ch->state = STFAX_ESCAPE; 517 ch->state = STFAX_ESCAPE;
518 /* set_skb_flag(skb, DF_NOMOREDATA); */ 518 /* set_skb_flag(skb, DF_NOMOREDATA); */
519 } 519 }
520 recv_Bchannel(&ch->bch, 0); 520 recv_Bchannel(&ch->bch, 0, false);
521 if (ch->is->cmsb & SART_NMD) 521 if (ch->is->cmsb & SART_NMD)
522 deliver_status(ch, HW_MOD_NOCARR); 522 deliver_status(ch, HW_MOD_NOCARR);
523 break; 523 break;
@@ -557,7 +557,7 @@ isar_rcv_frame(struct isar_ch *ch)
557 break; 557 break;
558 } 558 }
559 skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2); 559 skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
560 recv_Bchannel(&ch->bch, 0); 560 recv_Bchannel(&ch->bch, 0, false);
561 } 561 }
562 if (ch->is->cmsb & SART_NMD) { /* ABORT */ 562 if (ch->is->cmsb & SART_NMD) { /* ABORT */
563 pr_debug("%s: isar_rcv_frame: no more data\n", 563 pr_debug("%s: isar_rcv_frame: no more data\n",
@@ -1554,20 +1554,7 @@ isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
1554static int 1554static int
1555channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) 1555channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1556{ 1556{
1557 int ret = 0; 1557 return mISDN_ctrl_bchannel(bch, cq);
1558
1559 switch (cq->op) {
1560 case MISDN_CTRL_GETOP:
1561 cq->op = 0;
1562 break;
1563 /* Nothing implemented yet */
1564 case MISDN_CTRL_FILL_EMPTY:
1565 default:
1566 pr_info("%s: unknown Op %x\n", __func__, cq->op);
1567 ret = -EINVAL;
1568 break;
1569 }
1570 return ret;
1571} 1558}
1572 1559
1573static int 1560static int
@@ -1665,7 +1652,7 @@ mISDNisar_init(struct isar_hw *isar, void *hw)
1665 isar->hw = hw; 1652 isar->hw = hw;
1666 for (i = 0; i < 2; i++) { 1653 for (i = 0; i < 2; i++) {
1667 isar->ch[i].bch.nr = i + 1; 1654 isar->ch[i].bch.nr = i + 1;
1668 mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM); 1655 mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM, 32);
1669 isar->ch[i].bch.ch.nr = i + 1; 1656 isar->ch[i].bch.ch.nr = i + 1;
1670 isar->ch[i].bch.ch.send = &isar_l2l1; 1657 isar->ch[i].bch.ch.send = &isar_l2l1;
1671 isar->ch[i].bch.ch.ctrl = isar_bctrl; 1658 isar->ch[i].bch.ch.ctrl = isar_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
index 3f28057e725e..47d30749d8a7 100644
--- a/drivers/isdn/hardware/mISDN/netjet.c
+++ b/drivers/isdn/hardware/mISDN/netjet.c
@@ -408,7 +408,7 @@ read_dma(struct tiger_ch *bc, u32 idx, int cnt)
408 } 408 }
409 409
410 if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) { 410 if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) {
411 recv_Bchannel(&bc->bch, 0); 411 recv_Bchannel(&bc->bch, 0, false);
412 return; 412 return;
413 } 413 }
414 414
@@ -426,7 +426,7 @@ read_dma(struct tiger_ch *bc, u32 idx, int cnt)
426 DUMP_PREFIX_OFFSET, p, 426 DUMP_PREFIX_OFFSET, p,
427 stat); 427 stat);
428 } 428 }
429 recv_Bchannel(&bc->bch, 0); 429 recv_Bchannel(&bc->bch, 0, false);
430 stat = bchannel_get_rxbuf(&bc->bch, bc->bch.maxlen); 430 stat = bchannel_get_rxbuf(&bc->bch, bc->bch.maxlen);
431 if (stat < 0) { 431 if (stat < 0) {
432 pr_warning("%s.B%d: No memory for %d bytes\n", 432 pr_warning("%s.B%d: No memory for %d bytes\n",
@@ -758,21 +758,7 @@ nj_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
758static int 758static int
759channel_bctrl(struct tiger_ch *bc, struct mISDN_ctrl_req *cq) 759channel_bctrl(struct tiger_ch *bc, struct mISDN_ctrl_req *cq)
760{ 760{
761 int ret = 0; 761 return mISDN_ctrl_bchannel(&bc->bch, cq);
762 struct tiger_hw *card = bc->bch.hw;
763
764 switch (cq->op) {
765 case MISDN_CTRL_GETOP:
766 cq->op = 0;
767 break;
768 /* Nothing implemented yet */
769 case MISDN_CTRL_FILL_EMPTY:
770 default:
771 pr_info("%s: %s unknown Op %x\n", card->name, __func__, cq->op);
772 ret = -EINVAL;
773 break;
774 }
775 return ret;
776} 762}
777 763
778static int 764static int
@@ -1006,7 +992,8 @@ setup_instance(struct tiger_hw *card)
1006 for (i = 0; i < 2; i++) { 992 for (i = 0; i < 2; i++) {
1007 card->bc[i].bch.nr = i + 1; 993 card->bc[i].bch.nr = i + 1;
1008 set_channelmap(i + 1, card->isac.dch.dev.channelmap); 994 set_channelmap(i + 1, card->isac.dch.dev.channelmap);
1009 mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM); 995 mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM,
996 NJ_DMA_RXSIZE >> 1);
1010 card->bc[i].bch.hw = card; 997 card->bc[i].bch.hw = card;
1011 card->bc[i].bch.ch.send = nj_l2l1B; 998 card->bc[i].bch.ch.send = nj_l2l1B;
1012 card->bc[i].bch.ch.ctrl = nj_bctrl; 999 card->bc[i].bch.ch.ctrl = nj_bctrl;
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c
index 8324b20c7f16..03fb4a34fd53 100644
--- a/drivers/isdn/hardware/mISDN/w6692.c
+++ b/drivers/isdn/hardware/mISDN/w6692.c
@@ -688,7 +688,7 @@ W6692B_interrupt(struct w6692_hw *card, int ch)
688 if (count == 0) 688 if (count == 0)
689 count = W_B_FIFO_THRESH; 689 count = W_B_FIFO_THRESH;
690 W6692_empty_Bfifo(wch, count); 690 W6692_empty_Bfifo(wch, count);
691 recv_Bchannel(&wch->bch, 0); 691 recv_Bchannel(&wch->bch, 0, false);
692 } 692 }
693 } 693 }
694 if (stat & W_B_EXI_RMR) { 694 if (stat & W_B_EXI_RMR) {
@@ -704,9 +704,8 @@ W6692B_interrupt(struct w6692_hw *card, int ch)
704 W_B_CMDR_RRST | W_B_CMDR_RACT); 704 W_B_CMDR_RRST | W_B_CMDR_RACT);
705 } else { 705 } else {
706 W6692_empty_Bfifo(wch, W_B_FIFO_THRESH); 706 W6692_empty_Bfifo(wch, W_B_FIFO_THRESH);
707 if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags) && 707 if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
708 wch->bch.rx_skb && (wch->bch.rx_skb->len > 0)) 708 recv_Bchannel(&wch->bch, 0, false);
709 recv_Bchannel(&wch->bch, 0);
710 } 709 }
711 } 710 }
712 if (stat & W_B_EXI_RDOV) { 711 if (stat & W_B_EXI_RDOV) {
@@ -979,20 +978,7 @@ w6692_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
979static int 978static int
980channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) 979channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
981{ 980{
982 int ret = 0; 981 return mISDN_ctrl_bchannel(bch, cq);
983
984 switch (cq->op) {
985 case MISDN_CTRL_GETOP:
986 cq->op = 0;
987 break;
988 /* Nothing implemented yet */
989 case MISDN_CTRL_FILL_EMPTY:
990 default:
991 pr_info("%s: unknown Op %x\n", __func__, cq->op);
992 ret = -EINVAL;
993 break;
994 }
995 return ret;
996} 982}
997 983
998static int 984static int
@@ -1303,7 +1289,8 @@ setup_instance(struct w6692_hw *card)
1303 card->dch.hw = card; 1289 card->dch.hw = card;
1304 card->dch.dev.nrbchan = 2; 1290 card->dch.dev.nrbchan = 2;
1305 for (i = 0; i < 2; i++) { 1291 for (i = 0; i < 2; i++) {
1306 mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM); 1292 mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM,
1293 W_B_FIFO_THRESH);
1307 card->bc[i].bch.hw = card; 1294 card->bc[i].bch.hw = card;
1308 card->bc[i].bch.nr = i + 1; 1295 card->bc[i].bch.nr = i + 1;
1309 card->bc[i].bch.ch.nr = i + 1; 1296 card->bc[i].bch.ch.nr = i + 1;
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c
index 3c2145d8c3f8..d42ad0e98de3 100644
--- a/drivers/isdn/mISDN/hwchannel.c
+++ b/drivers/isdn/mISDN/hwchannel.c
@@ -81,10 +81,16 @@ mISDN_initdchannel(struct dchannel *ch, int maxlen, void *phf)
81EXPORT_SYMBOL(mISDN_initdchannel); 81EXPORT_SYMBOL(mISDN_initdchannel);
82 82
83int 83int
84mISDN_initbchannel(struct bchannel *ch, int maxlen) 84mISDN_initbchannel(struct bchannel *ch, unsigned short maxlen,
85 unsigned short minlen)
85{ 86{
86 ch->Flags = 0; 87 ch->Flags = 0;
88 ch->minlen = minlen;
89 ch->next_minlen = minlen;
90 ch->init_minlen = minlen;
87 ch->maxlen = maxlen; 91 ch->maxlen = maxlen;
92 ch->next_maxlen = maxlen;
93 ch->init_maxlen = maxlen;
88 ch->hw = NULL; 94 ch->hw = NULL;
89 ch->rx_skb = NULL; 95 ch->rx_skb = NULL;
90 ch->tx_skb = NULL; 96 ch->tx_skb = NULL;
@@ -134,6 +140,10 @@ mISDN_clear_bchannel(struct bchannel *ch)
134 test_and_clear_bit(FLG_TX_BUSY, &ch->Flags); 140 test_and_clear_bit(FLG_TX_BUSY, &ch->Flags);
135 test_and_clear_bit(FLG_TX_NEXT, &ch->Flags); 141 test_and_clear_bit(FLG_TX_NEXT, &ch->Flags);
136 test_and_clear_bit(FLG_ACTIVE, &ch->Flags); 142 test_and_clear_bit(FLG_ACTIVE, &ch->Flags);
143 ch->minlen = ch->init_minlen;
144 ch->next_minlen = ch->init_minlen;
145 ch->maxlen = ch->init_maxlen;
146 ch->next_maxlen = ch->init_maxlen;
137} 147}
138EXPORT_SYMBOL(mISDN_clear_bchannel); 148EXPORT_SYMBOL(mISDN_clear_bchannel);
139 149
@@ -148,6 +158,33 @@ mISDN_freebchannel(struct bchannel *ch)
148} 158}
149EXPORT_SYMBOL(mISDN_freebchannel); 159EXPORT_SYMBOL(mISDN_freebchannel);
150 160
161int
162mISDN_ctrl_bchannel(struct bchannel *bch, struct mISDN_ctrl_req *cq)
163{
164 int ret = 0;
165
166 switch (cq->op) {
167 case MISDN_CTRL_GETOP:
168 cq->op = MISDN_CTRL_RX_BUFFER;
169 break;
170 case MISDN_CTRL_RX_BUFFER:
171 if (cq->p2 > MISDN_CTRL_RX_SIZE_IGNORE)
172 bch->next_maxlen = cq->p2;
173 if (cq->p1 > MISDN_CTRL_RX_SIZE_IGNORE)
174 bch->next_minlen = cq->p1;
175 /* we return the old values */
176 cq->p1 = bch->minlen;
177 cq->p2 = bch->maxlen;
178 break;
179 default:
180 pr_info("mISDN unhandled control %x operation\n", cq->op);
181 ret = -EINVAL;
182 break;
183 }
184 return ret;
185}
186EXPORT_SYMBOL(mISDN_ctrl_bchannel);
187
151static inline u_int 188static inline u_int
152get_sapi_tei(u_char *p) 189get_sapi_tei(u_char *p)
153{ 190{
@@ -197,7 +234,7 @@ recv_Echannel(struct dchannel *ech, struct dchannel *dch)
197EXPORT_SYMBOL(recv_Echannel); 234EXPORT_SYMBOL(recv_Echannel);
198 235
199void 236void
200recv_Bchannel(struct bchannel *bch, unsigned int id) 237recv_Bchannel(struct bchannel *bch, unsigned int id, bool force)
201{ 238{
202 struct mISDNhead *hh; 239 struct mISDNhead *hh;
203 240
@@ -211,6 +248,9 @@ recv_Bchannel(struct bchannel *bch, unsigned int id)
211 dev_kfree_skb(bch->rx_skb); 248 dev_kfree_skb(bch->rx_skb);
212 bch->rx_skb = NULL; 249 bch->rx_skb = NULL;
213 } else { 250 } else {
251 if (test_bit(FLG_TRANSPARENT, &bch->Flags) &&
252 (bch->rx_skb->len < bch->minlen) && !force)
253 return;
214 hh = mISDN_HEAD_P(bch->rx_skb); 254 hh = mISDN_HEAD_P(bch->rx_skb);
215 hh->prim = PH_DATA_IND; 255 hh->prim = PH_DATA_IND;
216 hh->id = id; 256 hh->id = id;
@@ -426,7 +466,7 @@ bchannel_get_rxbuf(struct bchannel *bch, int reqlen)
426 bch->nr, reqlen, len); 466 bch->nr, reqlen, len);
427 if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { 467 if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
428 /* send what we have now and try a new buffer */ 468 /* send what we have now and try a new buffer */
429 recv_Bchannel(bch, 0); 469 recv_Bchannel(bch, 0, true);
430 } else { 470 } else {
431 /* on HDLC we have to drop too big frames */ 471 /* on HDLC we have to drop too big frames */
432 return -EMSGSIZE; 472 return -EMSGSIZE;
@@ -435,12 +475,25 @@ bchannel_get_rxbuf(struct bchannel *bch, int reqlen)
435 return len; 475 return len;
436 } 476 }
437 } 477 }
478 /* update current min/max length first */
479 if (unlikely(bch->maxlen != bch->next_maxlen))
480 bch->maxlen = bch->next_maxlen;
481 if (unlikely(bch->minlen != bch->next_minlen))
482 bch->minlen = bch->next_minlen;
438 if (unlikely(reqlen > bch->maxlen)) 483 if (unlikely(reqlen > bch->maxlen))
439 return -EMSGSIZE; 484 return -EMSGSIZE;
440 if (test_bit(FLG_TRANSPARENT, &bch->Flags)) 485 if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
441 len = reqlen; 486 if (reqlen >= bch->minlen) {
442 else /* with HDLC we do not know the length yet */ 487 len = reqlen;
488 } else {
489 len = 2 * bch->minlen;
490 if (len > bch->maxlen)
491 len = bch->maxlen;
492 }
493 } else {
494 /* with HDLC we do not know the length yet */
443 len = bch->maxlen; 495 len = bch->maxlen;
496 }
444 bch->rx_skb = mI_alloc_skb(len, GFP_ATOMIC); 497 bch->rx_skb = mI_alloc_skb(len, GFP_ATOMIC);
445 if (!bch->rx_skb) { 498 if (!bch->rx_skb) {
446 pr_warning("B%d receive no memory for %d bytes\n", 499 pr_warning("B%d receive no memory for %d bytes\n",
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
index 0f88acf1185f..db50f788855d 100644
--- a/drivers/isdn/mISDN/l1oip_core.c
+++ b/drivers/isdn/mISDN/l1oip_core.c
@@ -1420,7 +1420,7 @@ init_card(struct l1oip *hc, int pri, int bundle)
1420 bch->nr = i + ch; 1420 bch->nr = i + ch;
1421 bch->slot = i + ch; 1421 bch->slot = i + ch;
1422 bch->debug = debug; 1422 bch->debug = debug;
1423 mISDN_initbchannel(bch, MAX_DATA_MEM); 1423 mISDN_initbchannel(bch, MAX_DATA_MEM, 0);
1424 bch->hw = hc; 1424 bch->hw = hc;
1425 bch->ch.send = handle_bmsg; 1425 bch->ch.send = handle_bmsg;
1426 bch->ch.ctrl = l1oip_bctrl; 1426 bch->ch.ctrl = l1oip_bctrl;
diff --git a/include/linux/mISDNhw.h b/include/linux/mISDNhw.h
index a86d86beff73..226886cf31e7 100644
--- a/include/linux/mISDNhw.h
+++ b/include/linux/mISDNhw.h
@@ -154,7 +154,12 @@ struct bchannel {
154 struct timer_list timer; 154 struct timer_list timer;
155 /* receive data */ 155 /* receive data */
156 struct sk_buff *rx_skb; 156 struct sk_buff *rx_skb;
157 int maxlen; 157 unsigned short maxlen;
158 unsigned short init_maxlen; /* initial value */
159 unsigned short next_maxlen; /* pending value */
160 unsigned short minlen; /* for transparent data */
161 unsigned short init_minlen; /* initial value */
162 unsigned short next_minlen; /* pending value */
158 /* send data */ 163 /* send data */
159 struct sk_buff *next_skb; 164 struct sk_buff *next_skb;
160 struct sk_buff *tx_skb; 165 struct sk_buff *tx_skb;
@@ -169,10 +174,12 @@ struct bchannel {
169}; 174};
170 175
171extern int mISDN_initdchannel(struct dchannel *, int, void *); 176extern int mISDN_initdchannel(struct dchannel *, int, void *);
172extern int mISDN_initbchannel(struct bchannel *, int); 177extern int mISDN_initbchannel(struct bchannel *, unsigned short,
178 unsigned short);
173extern int mISDN_freedchannel(struct dchannel *); 179extern int mISDN_freedchannel(struct dchannel *);
174extern void mISDN_clear_bchannel(struct bchannel *); 180extern void mISDN_clear_bchannel(struct bchannel *);
175extern int mISDN_freebchannel(struct bchannel *); 181extern int mISDN_freebchannel(struct bchannel *);
182extern int mISDN_ctrl_bchannel(struct bchannel *, struct mISDN_ctrl_req *);
176extern void queue_ch_frame(struct mISDNchannel *, u_int, 183extern void queue_ch_frame(struct mISDNchannel *, u_int,
177 int, struct sk_buff *); 184 int, struct sk_buff *);
178extern int dchannel_senddata(struct dchannel *, struct sk_buff *); 185extern int dchannel_senddata(struct dchannel *, struct sk_buff *);
@@ -180,7 +187,7 @@ extern int bchannel_senddata(struct bchannel *, struct sk_buff *);
180extern int bchannel_get_rxbuf(struct bchannel *, int); 187extern int bchannel_get_rxbuf(struct bchannel *, int);
181extern void recv_Dchannel(struct dchannel *); 188extern void recv_Dchannel(struct dchannel *);
182extern void recv_Echannel(struct dchannel *, struct dchannel *); 189extern void recv_Echannel(struct dchannel *, struct dchannel *);
183extern void recv_Bchannel(struct bchannel *, unsigned int id); 190extern void recv_Bchannel(struct bchannel *, unsigned int, bool);
184extern void recv_Dchannel_skb(struct dchannel *, struct sk_buff *); 191extern void recv_Dchannel_skb(struct dchannel *, struct sk_buff *);
185extern void recv_Bchannel_skb(struct bchannel *, struct sk_buff *); 192extern void recv_Bchannel_skb(struct bchannel *, struct sk_buff *);
186extern int get_next_bframe(struct bchannel *); 193extern int get_next_bframe(struct bchannel *);
diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h
index ce6e613dff4c..246a3529ecf6 100644
--- a/include/linux/mISDNif.h
+++ b/include/linux/mISDNif.h
@@ -37,7 +37,7 @@
37 */ 37 */
38#define MISDN_MAJOR_VERSION 1 38#define MISDN_MAJOR_VERSION 1
39#define MISDN_MINOR_VERSION 1 39#define MISDN_MINOR_VERSION 1
40#define MISDN_RELEASE 28 40#define MISDN_RELEASE 29
41 41
42/* primitives for information exchange 42/* primitives for information exchange
43 * generell format 43 * generell format
@@ -365,6 +365,7 @@ clear_channelmap(u_int nr, u_char *map)
365#define MISDN_CTRL_LOOP 0x0001 365#define MISDN_CTRL_LOOP 0x0001
366#define MISDN_CTRL_CONNECT 0x0002 366#define MISDN_CTRL_CONNECT 0x0002
367#define MISDN_CTRL_DISCONNECT 0x0004 367#define MISDN_CTRL_DISCONNECT 0x0004
368#define MISDN_CTRL_RX_BUFFER 0x0008
368#define MISDN_CTRL_PCMCONNECT 0x0010 369#define MISDN_CTRL_PCMCONNECT 0x0010
369#define MISDN_CTRL_PCMDISCONNECT 0x0020 370#define MISDN_CTRL_PCMDISCONNECT 0x0020
370#define MISDN_CTRL_SETPEER 0x0040 371#define MISDN_CTRL_SETPEER 0x0040
@@ -387,6 +388,12 @@ clear_channelmap(u_int nr, u_char *map)
387#define MISDN_CTRL_HFC_WD_INIT 0x4009 388#define MISDN_CTRL_HFC_WD_INIT 0x4009
388#define MISDN_CTRL_HFC_WD_RESET 0x400A 389#define MISDN_CTRL_HFC_WD_RESET 0x400A
389 390
391/* special RX buffer value for MISDN_CTRL_RX_BUFFER request.p1 is the minimum
392 * buffer size request.p2 the maximum. Using MISDN_CTRL_RX_SIZE_IGNORE will
393 * not change the value, but still read back the actual stetting.
394 */
395#define MISDN_CTRL_RX_SIZE_IGNORE -1
396
390/* socket options */ 397/* socket options */
391#define MISDN_TIME_STAMP 0x0001 398#define MISDN_TIME_STAMP 0x0001
392 399