- move remaining HW drivers to mISDN
- fix possible race ->next_skb usage - helper for sending bchannel DATA INDICATION and CONFIRM
This commit is contained in:
parent
e872a653bd
commit
9f4e63a6c0
|
@ -21,7 +21,6 @@
|
||||||
#include "bchannel.h"
|
#include "bchannel.h"
|
||||||
#include "isac.h"
|
#include "isac.h"
|
||||||
#include "layer1.h"
|
#include "layer1.h"
|
||||||
#include "helper.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#define SPIN_DEBUG
|
#define SPIN_DEBUG
|
||||||
|
@ -282,7 +281,7 @@ __write_ctrl_pciv2(fritzpnppci *fc, hdlc_hw_t *hdlc, int channel) {
|
||||||
|
|
||||||
void
|
void
|
||||||
write_ctrl(bchannel_t *bch, int which) {
|
write_ctrl(bchannel_t *bch, int which) {
|
||||||
fritzpnppci *fc = bch->inst.data;
|
fritzpnppci *fc = bch->inst.privat;
|
||||||
hdlc_hw_t *hdlc = bch->hw;
|
hdlc_hw_t *hdlc = bch->hw;
|
||||||
|
|
||||||
if (fc->dch.debug & L1_DEB_HSCX)
|
if (fc->dch.debug & L1_DEB_HSCX)
|
||||||
|
@ -374,7 +373,7 @@ modehdlc(bchannel_t *bch, int bc, int protocol)
|
||||||
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
|
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
|
||||||
write_ctrl(bch, 1);
|
write_ctrl(bch, 1);
|
||||||
hdlc->ctrl.sr.cmd = 0;
|
hdlc->ctrl.sr.cmd = 0;
|
||||||
bch_sched_event(bch, B_XMTBUFREADY);
|
// FIXME bch_sched_event(bch, B_XMTBUFREADY);
|
||||||
break;
|
break;
|
||||||
case (ISDN_PID_L1_B_64HDLC):
|
case (ISDN_PID_L1_B_64HDLC):
|
||||||
bch->protocol = protocol;
|
bch->protocol = protocol;
|
||||||
|
@ -384,7 +383,7 @@ modehdlc(bchannel_t *bch, int bc, int protocol)
|
||||||
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
|
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
|
||||||
write_ctrl(bch, 1);
|
write_ctrl(bch, 1);
|
||||||
hdlc->ctrl.sr.cmd = 0;
|
hdlc->ctrl.sr.cmd = 0;
|
||||||
bch_sched_event(bch, B_XMTBUFREADY);
|
// FIXME bch_sched_event(bch, B_XMTBUFREADY);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mISDN_debugprint(&bch->inst, "prot not known %x", protocol);
|
mISDN_debugprint(&bch->inst, "prot not known %x", protocol);
|
||||||
|
@ -400,7 +399,7 @@ hdlc_empty_fifo(bchannel_t *bch, int count)
|
||||||
u_char *p;
|
u_char *p;
|
||||||
u_char idx = bch->channel ? AVM_HDLC_2 : AVM_HDLC_1;
|
u_char idx = bch->channel ? AVM_HDLC_2 : AVM_HDLC_1;
|
||||||
int cnt=0;
|
int cnt=0;
|
||||||
fritzpnppci *fc = bch->inst.data;
|
fritzpnppci *fc = bch->inst.privat;
|
||||||
|
|
||||||
if ((fc->dch.debug & L1_DEB_HSCX) && !(fc->dch.debug & L1_DEB_HSCX_FIFO))
|
if ((fc->dch.debug & L1_DEB_HSCX) && !(fc->dch.debug & L1_DEB_HSCX_FIFO))
|
||||||
mISDN_debugprint(&bch->inst, "hdlc_empty_fifo %d", count);
|
mISDN_debugprint(&bch->inst, "hdlc_empty_fifo %d", count);
|
||||||
|
@ -463,7 +462,7 @@ hdlc_empty_fifo(bchannel_t *bch, int count)
|
||||||
static void
|
static void
|
||||||
hdlc_fill_fifo(bchannel_t *bch)
|
hdlc_fill_fifo(bchannel_t *bch)
|
||||||
{
|
{
|
||||||
fritzpnppci *fc = bch->inst.data;
|
fritzpnppci *fc = bch->inst.privat;
|
||||||
hdlc_hw_t *hdlc = bch->hw;
|
hdlc_hw_t *hdlc = bch->hw;
|
||||||
int count, cnt =0;
|
int count, cnt =0;
|
||||||
u_char *p;
|
u_char *p;
|
||||||
|
@ -542,21 +541,28 @@ HDLC_irq_xpr(bchannel_t *bch)
|
||||||
hdlc_fill_fifo(bch);
|
hdlc_fill_fifo(bch);
|
||||||
else {
|
else {
|
||||||
bch->tx_idx = 0;
|
bch->tx_idx = 0;
|
||||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
if (test_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||||
if (bch->next_skb) {
|
struct sk_buff *skb = bch->next_skb;
|
||||||
bch->tx_len = bch->next_skb->len;
|
mISDN_head_t *hh;
|
||||||
memcpy(bch->tx_buf, bch->next_skb->data, bch->tx_len);
|
if (skb) {
|
||||||
|
bch->next_skb = NULL;
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
|
hh = mISDN_HEAD_P(skb);
|
||||||
|
bch->tx_len = skb->len;
|
||||||
|
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||||
hdlc_fill_fifo(bch);
|
hdlc_fill_fifo(bch);
|
||||||
|
skb_trim(skb, 0);
|
||||||
|
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||||
} else {
|
} else {
|
||||||
bch->tx_len = 0;
|
bch->tx_len = 0;
|
||||||
printk(KERN_WARNING "hdlc tx irq TX_NEXT without skb\n");
|
printk(KERN_WARNING "hdlc tx irq TX_NEXT without skb\n");
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bch->tx_len = 0;
|
bch->tx_len = 0;
|
||||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||||
}
|
}
|
||||||
bch_sched_event(bch, B_XMTBUFREADY);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,10 +599,9 @@ HDLC_irq(bchannel_t *bch, u_int stat)
|
||||||
else {
|
else {
|
||||||
memcpy(skb_put(skb, bch->rx_idx),
|
memcpy(skb_put(skb, bch->rx_idx),
|
||||||
bch->rx_buf, bch->rx_idx);
|
bch->rx_buf, bch->rx_idx);
|
||||||
skb_queue_tail(&bch->rqueue, skb);
|
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||||
}
|
}
|
||||||
bch->rx_idx = 0;
|
bch->rx_idx = 0;
|
||||||
bch_sched_event(bch, B_RCVBUFREADY);
|
|
||||||
} else {
|
} else {
|
||||||
if (bch->debug & L1_DEB_HSCX)
|
if (bch->debug & L1_DEB_HSCX)
|
||||||
mISDN_debugprint(&bch->inst, "invalid frame");
|
mISDN_debugprint(&bch->inst, "invalid frame");
|
||||||
|
@ -811,54 +816,52 @@ avm_fritzv2_interrupt(int intno, void *dev_id, struct pt_regs *regs)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
hdlc_down(mISDNif_t *hif, struct sk_buff *skb)
|
hdlc_down(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
bchannel_t *bch;
|
bchannel_t *bch;
|
||||||
int ret = -EINVAL;
|
int ret = 0;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh;
|
||||||
|
|
||||||
if (!hif || !skb)
|
|
||||||
return(ret);
|
|
||||||
hh = mISDN_HEAD_P(skb);
|
hh = mISDN_HEAD_P(skb);
|
||||||
bch = hif->fdata;
|
bch = container_of(inst, bchannel_t, inst);
|
||||||
if ((hh->prim == PH_DATA_REQ) ||
|
if ((hh->prim == PH_DATA_REQ) ||
|
||||||
(hh->prim == (DL_DATA | REQUEST))) {
|
(hh->prim == (DL_DATA | REQUEST))) {
|
||||||
if (bch->next_skb) {
|
if (bch->next_skb) {
|
||||||
mISDN_debugprint(&bch->inst, " l2l1 next_skb exist this shouldn't happen");
|
mISDN_debugprint(&bch->inst, " l2l1 next_skb exist this shouldn't happen");
|
||||||
return(-EBUSY);
|
return(-EBUSY);
|
||||||
}
|
}
|
||||||
bch->inst.lock(bch->inst.data, 0);
|
if (skb->len <= 0)
|
||||||
|
return(-EINVAL);
|
||||||
|
bch->inst.lock(bch->inst.privat, 0);
|
||||||
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
|
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
|
||||||
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
bch->next_skb = skb;
|
bch->next_skb = skb;
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
return(0);
|
return(0);
|
||||||
} else {
|
} else {
|
||||||
bch->tx_len = skb->len;
|
bch->tx_len = skb->len;
|
||||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||||
bch->tx_idx = 0;
|
bch->tx_idx = 0;
|
||||||
hdlc_fill_fifo(bch);
|
hdlc_fill_fifo(bch);
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
return(if_newhead(&bch->inst.up, hh->prim | CONFIRM,
|
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM,
|
||||||
hh->dinfo, skb));
|
hh->dinfo, skb));
|
||||||
}
|
}
|
||||||
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
|
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
|
||||||
(hh->prim == (DL_ESTABLISH | REQUEST))) {
|
(hh->prim == (DL_ESTABLISH | REQUEST))) {
|
||||||
if (test_and_set_bit(BC_FLG_ACTIV, &bch->Flag))
|
if (!test_and_set_bit(BC_FLG_ACTIV, &bch->Flag)) {
|
||||||
ret = 0;
|
bch->inst.lock(bch->inst.privat,0);
|
||||||
else {
|
|
||||||
bch->inst.lock(bch->inst.data,0);
|
|
||||||
ret = modehdlc(bch, bch->channel,
|
ret = modehdlc(bch, bch->channel,
|
||||||
bch->inst.pid.protocol[1]);
|
bch->inst.pid.protocol[1]);
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
}
|
}
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
return(if_newhead(&bch->inst.up, hh->prim | CONFIRM, ret, skb));
|
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, ret, skb));
|
||||||
} else if ((hh->prim == (PH_DEACTIVATE | REQUEST)) ||
|
} else if ((hh->prim == (PH_DEACTIVATE | REQUEST)) ||
|
||||||
(hh->prim == (DL_RELEASE | REQUEST)) ||
|
(hh->prim == (DL_RELEASE | REQUEST)) ||
|
||||||
(hh->prim == (MGR_DISCONNECT | REQUEST))) {
|
((hh->prim == (PH_CONTROL | REQUEST) && (hh->dinfo == HW_DEACTIVATE)))) {
|
||||||
bch->inst.lock(bch->inst.data,0);
|
bch->inst.lock(bch->inst.privat,0);
|
||||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||||
dev_kfree_skb(bch->next_skb);
|
dev_kfree_skb(bch->next_skb);
|
||||||
bch->next_skb = NULL;
|
bch->next_skb = NULL;
|
||||||
|
@ -866,12 +869,10 @@ hdlc_down(mISDNif_t *hif, struct sk_buff *skb)
|
||||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||||
modehdlc(bch, bch->channel, 0);
|
modehdlc(bch, bch->channel, 0);
|
||||||
test_and_clear_bit(BC_FLG_ACTIV, &bch->Flag);
|
test_and_clear_bit(BC_FLG_ACTIV, &bch->Flag);
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
if (hh->prim != (MGR_DISCONNECT | REQUEST))
|
if (hh->prim != (PH_CONTROL | REQUEST))
|
||||||
if (!if_newhead(&bch->inst.up, hh->prim | CONFIRM, 0, skb))
|
ret = mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, 0, skb);
|
||||||
return(0);
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "hdlc_down unknown prim(%x)\n", hh->prim);
|
printk(KERN_WARNING "hdlc_down unknown prim(%x)\n", hh->prim);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -1108,7 +1109,6 @@ release_card(fritzpnppci *card)
|
||||||
mISDN_free_bch(&card->bch[1]);
|
mISDN_free_bch(&card->bch[1]);
|
||||||
mISDN_free_bch(&card->bch[0]);
|
mISDN_free_bch(&card->bch[0]);
|
||||||
mISDN_free_dch(&card->dch);
|
mISDN_free_dch(&card->dch);
|
||||||
fritz.ctrl(card->dch.inst.up.peer, MGR_DISCONNECT | REQUEST, &card->dch.inst.up);
|
|
||||||
fritz.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
|
fritz.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||||
list_del(&card->list);
|
list_del(&card->list);
|
||||||
unlock_dev(card);
|
unlock_dev(card);
|
||||||
|
@ -1166,22 +1166,17 @@ fritz_manager(void *data, u_int prim, void *arg) {
|
||||||
bch_set_para(&card->bch[channel], &inst->st->para);
|
bch_set_para(&card->bch[channel], &inst->st->para);
|
||||||
break;
|
break;
|
||||||
case MGR_UNREGLAYER | REQUEST:
|
case MGR_UNREGLAYER | REQUEST:
|
||||||
if (channel == 2) {
|
|
||||||
inst->down.fdata = &card->dch;
|
|
||||||
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
||||||
HW_DEACTIVATE, 0, NULL, 0))) {
|
HW_DEACTIVATE, 0, NULL, 0))) {
|
||||||
if (mISDN_ISAC_l1hw(&inst->down, skb))
|
if (channel == 2) {
|
||||||
|
if (mISDN_ISAC_l1hw(inst, skb))
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
inst->down.fdata = &card->bch[channel];
|
if (hdlc_down(inst, skb))
|
||||||
if ((skb = create_link_skb(MGR_DISCONNECT | REQUEST,
|
|
||||||
0, 0, NULL, 0))) {
|
|
||||||
if (hdlc_down(&inst->down, skb))
|
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
fritz.ctrl(inst->up.peer, MGR_DISCONNECT | REQUEST, &inst->up);
|
printk(KERN_WARNING "no SKB in %s MGR_UNREGLAYER | REQUEST\n", __FUNCTION__);
|
||||||
fritz.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
|
fritz.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||||
break;
|
break;
|
||||||
case MGR_CLRSTPARA | INDICATION:
|
case MGR_CLRSTPARA | INDICATION:
|
||||||
|
@ -1199,33 +1194,18 @@ fritz_manager(void *data, u_int prim, void *arg) {
|
||||||
fritz.refcnt--;
|
fritz.refcnt--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MGR_CONNECT | REQUEST:
|
|
||||||
return(mISDN_ConnectIF(inst, arg));
|
|
||||||
case MGR_SETIF | REQUEST:
|
|
||||||
case MGR_SETIF | INDICATION:
|
|
||||||
if (channel==2)
|
|
||||||
return(mISDN_SetIF(inst, arg, prim, mISDN_ISAC_l1hw, NULL,
|
|
||||||
&card->dch));
|
|
||||||
else
|
|
||||||
return(mISDN_SetIF(inst, arg, prim, hdlc_down, NULL,
|
|
||||||
&card->bch[channel]));
|
|
||||||
break;
|
|
||||||
case MGR_DISCONNECT | REQUEST:
|
|
||||||
case MGR_DISCONNECT | INDICATION:
|
|
||||||
return(mISDN_DisConnectIF(inst, arg));
|
|
||||||
case MGR_SETSTACK | INDICATION:
|
case MGR_SETSTACK | INDICATION:
|
||||||
if ((channel!=2) && (inst->pid.global == 2)) {
|
if ((channel!=2) && (inst->pid.global == 2)) {
|
||||||
inst->down.fdata = &card->bch[channel];
|
|
||||||
if ((skb = create_link_skb(PH_ACTIVATE | REQUEST,
|
if ((skb = create_link_skb(PH_ACTIVATE | REQUEST,
|
||||||
0, 0, NULL, 0))) {
|
0, 0, NULL, 0))) {
|
||||||
if (hdlc_down(&inst->down, skb))
|
if (hdlc_down(inst, skb))
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
}
|
}
|
||||||
if (inst->pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
if (inst->pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
||||||
if_link(&inst->up, DL_ESTABLISH | INDICATION,
|
mISDN_queue_data(inst, FLG_MSG_UP, DL_ESTABLISH | INDICATION,
|
||||||
0, 0, NULL, 0);
|
0, 0, NULL, 0);
|
||||||
else
|
else
|
||||||
if_link(&inst->up, PH_ACTIVATE | INDICATION,
|
mISDN_queue_data(inst, FLG_MSG_UP, PH_ACTIVATE | INDICATION,
|
||||||
0, 0, NULL, 0);
|
0, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1251,13 +1231,13 @@ static int __devinit setup_instance(fritzpnppci *card)
|
||||||
card->dch.inst.unlock = unlock_dev;
|
card->dch.inst.unlock = unlock_dev;
|
||||||
card->dch.inst.pid.layermask = ISDN_LAYER(0);
|
card->dch.inst.pid.layermask = ISDN_LAYER(0);
|
||||||
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_TE_S0;
|
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_TE_S0;
|
||||||
mISDN_init_instance(&card->dch.inst, &fritz, card);
|
mISDN_init_instance(&card->dch.inst, &fritz, card, mISDN_ISAC_l1hw);
|
||||||
sprintf(card->dch.inst.name, "Fritz%d", fritz_cnt+1);
|
sprintf(card->dch.inst.name, "Fritz%d", fritz_cnt+1);
|
||||||
mISDN_set_dchannel_pid(&pid, protocol[fritz_cnt], layermask[fritz_cnt]);
|
mISDN_set_dchannel_pid(&pid, protocol[fritz_cnt], layermask[fritz_cnt]);
|
||||||
mISDN_init_dch(&card->dch);
|
mISDN_init_dch(&card->dch);
|
||||||
for (i=0; i<2; i++) {
|
for (i=0; i<2; i++) {
|
||||||
card->bch[i].channel = i;
|
card->bch[i].channel = i;
|
||||||
mISDN_init_instance(&card->bch[i].inst, &fritz, card);
|
mISDN_init_instance(&card->bch[i].inst, &fritz, card, hdlc_down);
|
||||||
card->bch[i].inst.pid.layermask = ISDN_LAYER(0);
|
card->bch[i].inst.pid.layermask = ISDN_LAYER(0);
|
||||||
card->bch[i].inst.lock = lock_dev;
|
card->bch[i].inst.lock = lock_dev;
|
||||||
card->bch[i].inst.unlock = unlock_dev;
|
card->bch[i].inst.unlock = unlock_dev;
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
* This file is (c) under GNU PUBLIC LICENSE
|
* This file is (c) under GNU PUBLIC LICENSE
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
#ifndef _mISDN_BCHANNEL_H
|
||||||
|
#define _mISDN_BCHANNEL_H
|
||||||
#include <linux/mISDNif.h>
|
#include <linux/mISDNif.h>
|
||||||
#ifdef HAS_WORKQUEUE
|
#ifdef HAS_WORKQUEUE
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
#ifdef MISDN_MEMDEBUG
|
#ifdef MISDN_MEMDEBUG
|
||||||
#include "memdbg.h"
|
#include "memdbg.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "helper.h"
|
||||||
|
|
||||||
#define MAX_BLOG_SPACE 256
|
#define MAX_BLOG_SPACE 256
|
||||||
|
|
||||||
|
@ -92,6 +94,19 @@ bch_set_para(bchannel_t *bch, mISDN_stPara_t *stp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
queue_bch_frame(bchannel_t *bch, u_int pr, int dinfo, struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
||||||
|
pr |= DL_DATA;
|
||||||
|
else
|
||||||
|
pr |= PH_DATA;
|
||||||
|
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, dinfo, skb))) {
|
||||||
|
int_error();
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef OBSOLETE
|
#ifdef OBSOLETE
|
||||||
static inline void
|
static inline void
|
||||||
bch_sched_event(bchannel_t *bch, int event)
|
bch_sched_event(bchannel_t *bch, int event)
|
||||||
|
@ -100,3 +115,4 @@ bch_sched_event(bchannel_t *bch, int event)
|
||||||
schedule_work(&bch->work);
|
schedule_work(&bch->work);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
|
@ -101,7 +101,6 @@
|
||||||
#include "bchannel.h"
|
#include "bchannel.h"
|
||||||
#include "layer1.h"
|
#include "layer1.h"
|
||||||
#include "dsp.h"
|
#include "dsp.h"
|
||||||
#include "helper.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include <linux/isdn_compat.h>
|
#include <linux/isdn_compat.h>
|
||||||
|
|
||||||
|
@ -1013,11 +1012,12 @@ next_frame:
|
||||||
} */
|
} */
|
||||||
|
|
||||||
// check for next frame
|
// check for next frame
|
||||||
if (test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
if (test_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||||
struct sk_buff *skb = dch->next_skb;
|
struct sk_buff *skb = dch->next_skb;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh;
|
||||||
if (skb) {
|
if (skb) {
|
||||||
dch->next_skb = NULL;
|
dch->next_skb = NULL;
|
||||||
|
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
hh = mISDN_HEAD_P(skb);
|
hh = mISDN_HEAD_P(skb);
|
||||||
dch->tx_idx = 0;
|
dch->tx_idx = 0;
|
||||||
dch->tx_len = skb->len;
|
dch->tx_len = skb->len;
|
||||||
|
@ -1025,38 +1025,35 @@ next_frame:
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
if (mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_CNF, hh->dinfo, skb)) dev_kfree_skb(skb);
|
if (mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_CNF, hh->dinfo, skb)) dev_kfree_skb(skb);
|
||||||
goto next_frame;
|
goto next_frame;
|
||||||
} else
|
} else {
|
||||||
|
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
printk(KERN_WARNING "%s: tx irq TX_NEXT without skb (dch ch=%d)\n", __FUNCTION__, ch);
|
printk(KERN_WARNING "%s: tx irq TX_NEXT without skb (dch ch=%d)\n", __FUNCTION__, ch);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
||||||
dch->tx_idx = dch->tx_len = 0;
|
dch->tx_idx = dch->tx_len = 0;
|
||||||
}
|
}
|
||||||
if (bch) {
|
if (bch) {
|
||||||
// check for next frame
|
// check for next frame
|
||||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
if (test_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||||
struct sk_buff *skb = bch->next_skb;
|
struct sk_buff *skb = bch->next_skb;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh;
|
||||||
u_int pr;
|
|
||||||
if (skb) {
|
if (skb) {
|
||||||
bch->next_skb = NULL;
|
bch->next_skb = NULL;
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
hh = mISDN_HEAD_P(skb);
|
hh = mISDN_HEAD_P(skb);
|
||||||
bch->tx_idx = 0;
|
bch->tx_idx = 0;
|
||||||
bch->tx_len = skb->len;
|
bch->tx_len = skb->len;
|
||||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||||
pr = DL_DATA | CONFIRM;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | CONFIRM;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, hh->dinfo, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
goto next_frame;
|
goto next_frame;
|
||||||
} else
|
} else {
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
printk(KERN_WARNING "hfcB tx irq TX_NEXT without skb\n");
|
printk(KERN_WARNING "hfcB tx irq TX_NEXT without skb\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||||
bch->tx_idx = bch->tx_len = 0;
|
bch->tx_idx = bch->tx_len = 0;
|
||||||
|
@ -1262,17 +1259,8 @@ next_frame:
|
||||||
// schedule D-channel event
|
// schedule D-channel event
|
||||||
mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_IND, MISDN_ID_ANY, skb);
|
mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_IND, MISDN_ID_ANY, skb);
|
||||||
}
|
}
|
||||||
if (bch) {
|
if (bch)
|
||||||
// schedule B-channel event
|
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
|
||||||
pr = DL_DATA | INDICATION;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | INDICATION;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, MISDN_ID_ANY, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*idx = 0;
|
*idx = 0;
|
||||||
goto next_frame;
|
goto next_frame;
|
||||||
}
|
}
|
||||||
|
@ -1301,19 +1289,8 @@ next_frame:
|
||||||
//dchannel_sched_event(dch, D_RCVBUFREADY);
|
//dchannel_sched_event(dch, D_RCVBUFREADY);
|
||||||
mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_IND, MISDN_ID_ANY, skb);
|
mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_IND, MISDN_ID_ANY, skb);
|
||||||
}
|
}
|
||||||
if (bch) {
|
if (bch)
|
||||||
// schedule B-channel event
|
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||||
//skb_queue_tail(&bch->rqueue, skb);
|
|
||||||
//bch_sched_event(bch, B_RCVBUFREADY);
|
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
|
||||||
pr = DL_DATA | INDICATION;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | INDICATION;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, MISDN_ID_ANY, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "bchannel.h"
|
#include "bchannel.h"
|
||||||
#include "hfc_pci.h"
|
#include "hfc_pci.h"
|
||||||
#include "layer1.h"
|
#include "layer1.h"
|
||||||
#include "helper.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include <linux/isdn_compat.h>
|
#include <linux/isdn_compat.h>
|
||||||
|
|
||||||
|
@ -546,7 +545,6 @@ hfcpci_empty_fifo_trans(bchannel_t *bch, bzfifo_type * bz, u_char * bdata)
|
||||||
{
|
{
|
||||||
unsigned short *z1r, *z2r;
|
unsigned short *z1r, *z2r;
|
||||||
int new_z2, fcnt, maxlen;
|
int new_z2, fcnt, maxlen;
|
||||||
u_int pr;
|
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
u_char *ptr, *ptr1;
|
u_char *ptr, *ptr1;
|
||||||
|
|
||||||
|
@ -583,14 +581,7 @@ hfcpci_empty_fifo_trans(bchannel_t *bch, bzfifo_type * bz, u_char * bdata)
|
||||||
ptr1 = bdata; /* start of buffer */
|
ptr1 = bdata; /* start of buffer */
|
||||||
memcpy(ptr, ptr1, fcnt); /* rest */
|
memcpy(ptr, ptr1, fcnt); /* rest */
|
||||||
}
|
}
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||||
pr = DL_DATA | INDICATION;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | INDICATION;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, MISDN_ID_ANY, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*z2r = new_z2; /* new position */
|
*z2r = new_z2; /* new position */
|
||||||
|
@ -606,7 +597,6 @@ main_rec_hfcpci(bchannel_t *bch)
|
||||||
hfc_pci_t *hc = bch->hw;
|
hfc_pci_t *hc = bch->hw;
|
||||||
int rcnt, real_fifo;
|
int rcnt, real_fifo;
|
||||||
int receive, count = 5;
|
int receive, count = 5;
|
||||||
u_int pr;
|
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
bzfifo_type *bz;
|
bzfifo_type *bz;
|
||||||
u_char *bdata;
|
u_char *bdata;
|
||||||
|
@ -638,14 +628,7 @@ main_rec_hfcpci(bchannel_t *bch)
|
||||||
mISDN_debugprint(&bch->inst, "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)",
|
mISDN_debugprint(&bch->inst, "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)",
|
||||||
bch->channel, zp->z1, zp->z2, rcnt);
|
bch->channel, zp->z1, zp->z2, rcnt);
|
||||||
if ((skb = hfcpci_empty_fifo(bch, bz, bdata, rcnt))) {
|
if ((skb = hfcpci_empty_fifo(bch, bz, bdata, rcnt))) {
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||||
pr = DL_DATA | INDICATION;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | INDICATION;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, MISDN_ID_ANY, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
rcnt = bz->f1 - bz->f2;
|
rcnt = bz->f1 - bz->f2;
|
||||||
if (rcnt < 0)
|
if (rcnt < 0)
|
||||||
|
@ -814,29 +797,24 @@ next_t_frame:
|
||||||
} else if (bch->debug & L1_DEB_HSCX)
|
} else if (bch->debug & L1_DEB_HSCX)
|
||||||
mISDN_debugprint(&bch->inst, "hfcpci_fill_fifo_trans ch(%x) frame length %d discarded",
|
mISDN_debugprint(&bch->inst, "hfcpci_fill_fifo_trans ch(%x) frame length %d discarded",
|
||||||
bch->channel, bch->tx_len);
|
bch->channel, bch->tx_len);
|
||||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
if (test_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||||
struct sk_buff *skb = bch->next_skb;
|
struct sk_buff *skb = bch->next_skb;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh;
|
||||||
u_int pr;
|
|
||||||
if (skb) {
|
if (skb) {
|
||||||
bch->next_skb = NULL;
|
bch->next_skb = NULL;
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
hh = mISDN_HEAD_P(skb);
|
hh = mISDN_HEAD_P(skb);
|
||||||
bch->tx_idx = 0;
|
bch->tx_idx = 0;
|
||||||
bch->tx_len = skb->len;
|
bch->tx_len = skb->len;
|
||||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||||
pr = DL_DATA | CONFIRM;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | CONFIRM;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, hh->dinfo, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
goto next_t_frame;
|
goto next_t_frame;
|
||||||
} else
|
} else {
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
printk(KERN_WARNING "hfcB tx irq TX_NEXT without skb\n");
|
printk(KERN_WARNING "hfcB tx irq TX_NEXT without skb\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
bch->tx_len = 0;
|
bch->tx_len = 0;
|
||||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||||
bch->tx_idx = bch->tx_len;
|
bch->tx_idx = bch->tx_len;
|
||||||
|
@ -1288,28 +1266,22 @@ hfcpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
|
||||||
hfcpci_fill_fifo(bch);
|
hfcpci_fill_fifo(bch);
|
||||||
} else {
|
} else {
|
||||||
bch->tx_idx = 0;
|
bch->tx_idx = 0;
|
||||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
if (test_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||||
struct sk_buff *skb = bch->next_skb;
|
struct sk_buff *skb = bch->next_skb;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh;
|
||||||
u_int pr;
|
|
||||||
if (skb) {
|
if (skb) {
|
||||||
bch->next_skb = NULL;
|
bch->next_skb = NULL;
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
hh = mISDN_HEAD_P(skb);
|
hh = mISDN_HEAD_P(skb);
|
||||||
bch->tx_idx = 0;
|
bch->tx_idx = 0;
|
||||||
bch->tx_len = skb->len;
|
bch->tx_len = skb->len;
|
||||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||||
pr = DL_DATA | CONFIRM;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | CONFIRM;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, hh->dinfo, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
hfcpci_fill_fifo(bch);
|
hfcpci_fill_fifo(bch);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "hfcB tx irq TX_NEXT without skb\n");
|
printk(KERN_WARNING "hfcB tx irq TX_NEXT without skb\n");
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||||
bch->tx_len = 0;
|
bch->tx_len = 0;
|
||||||
}
|
}
|
||||||
|
@ -1330,28 +1302,22 @@ hfcpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
|
||||||
hfcpci_fill_fifo(bch);
|
hfcpci_fill_fifo(bch);
|
||||||
} else {
|
} else {
|
||||||
bch->tx_idx = 0;
|
bch->tx_idx = 0;
|
||||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
if (test_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||||
struct sk_buff *skb = bch->next_skb;
|
struct sk_buff *skb = bch->next_skb;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh;
|
||||||
u_int pr;
|
|
||||||
if (skb) {
|
if (skb) {
|
||||||
bch->next_skb = NULL;
|
bch->next_skb = NULL;
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
hh = mISDN_HEAD_P(skb);
|
hh = mISDN_HEAD_P(skb);
|
||||||
bch->tx_idx = 0;
|
bch->tx_idx = 0;
|
||||||
bch->tx_len = skb->len;
|
bch->tx_len = skb->len;
|
||||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||||
pr = DL_DATA | CONFIRM;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | CONFIRM;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, hh->dinfo, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
hfcpci_fill_fifo(bch);
|
hfcpci_fill_fifo(bch);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "hfcB tx irq TX_NEXT without skb\n");
|
printk(KERN_WARNING "hfcB tx irq TX_NEXT without skb\n");
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||||
bch->tx_len = 0;
|
bch->tx_len = 0;
|
||||||
}
|
}
|
||||||
|
@ -1376,22 +1342,23 @@ hfcpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
|
||||||
if (hc->dch.tx_idx < hc->dch.tx_len) {
|
if (hc->dch.tx_idx < hc->dch.tx_len) {
|
||||||
hfcpci_fill_dfifo(hc);
|
hfcpci_fill_dfifo(hc);
|
||||||
} else {
|
} else {
|
||||||
if (test_and_clear_bit(FLG_TX_NEXT, &hc->dch.DFlags)) {
|
if (test_bit(FLG_TX_NEXT, &hc->dch.DFlags)) {
|
||||||
if (hc->dch.next_skb) {
|
struct sk_buff *skb = hc->dch.next_skb;
|
||||||
mISDN_head_t *hh;
|
if (skb) {
|
||||||
hc->dch.tx_len = hc->dch.next_skb->len;
|
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||||
memcpy(hc->dch.tx_buf,
|
|
||||||
hc->dch.next_skb->data,
|
hc->dch.next_skb= NULL;
|
||||||
hc->dch.tx_len);
|
test_and_clear_bit(FLG_TX_NEXT, &hc->dch.DFlags);
|
||||||
|
hc->dch.tx_len = skb->len;
|
||||||
|
memcpy(hc->dch.tx_buf, skb->data, hc->dch.tx_len);
|
||||||
hc->dch.tx_idx = 0;
|
hc->dch.tx_idx = 0;
|
||||||
hfcpci_fill_dfifo(hc);
|
hfcpci_fill_dfifo(hc);
|
||||||
skb_trim(hc->dch.next_skb, 0);
|
skb_trim(skb, 0);
|
||||||
hh = mISDN_HEAD_P(hc->dch.next_skb);
|
if (mISDN_queueup_newhead(&hc->dch.inst, 0, PH_DATA_CNF, hh->dinfo, skb))
|
||||||
if (mISDN_queueup_newhead(&hc->dch.inst, 0, PH_DATA_CNF, hh->dinfo, hc->dch.next_skb))
|
dev_kfree_skb(skb);
|
||||||
dev_kfree_skb(hc->dch.next_skb);
|
|
||||||
hc->dch.next_skb= NULL;
|
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "hfcd tx irq TX_NEXT without skb\n");
|
printk(KERN_WARNING "hfcd tx irq TX_NEXT without skb\n");
|
||||||
|
test_and_clear_bit(FLG_TX_NEXT, &hc->dch.DFlags);
|
||||||
test_and_clear_bit(FLG_TX_BUSY, &hc->dch.DFlags);
|
test_and_clear_bit(FLG_TX_BUSY, &hc->dch.DFlags);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -1432,13 +1399,12 @@ HFCD_l1hw(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
dchannel_t *dch;
|
dchannel_t *dch;
|
||||||
hfc_pci_t *hc;
|
hfc_pci_t *hc;
|
||||||
int ret = -EINVAL;
|
int ret = 0;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh;
|
||||||
|
|
||||||
hh = mISDN_HEAD_P(skb);
|
hh = mISDN_HEAD_P(skb);
|
||||||
dch = container_of(inst, dchannel_t, inst);
|
dch = container_of(inst, dchannel_t, inst);
|
||||||
hc = inst->privat;
|
hc = inst->privat;
|
||||||
ret = 0;
|
|
||||||
if (hh->prim == PH_DATA_REQ) {
|
if (hh->prim == PH_DATA_REQ) {
|
||||||
if (dch->next_skb) {
|
if (dch->next_skb) {
|
||||||
printk(KERN_WARNING "%s: next_skb exist ERROR\n", __FUNCTION__);
|
printk(KERN_WARNING "%s: next_skb exist ERROR\n", __FUNCTION__);
|
||||||
|
@ -1571,7 +1537,7 @@ HFCD_l1hw(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||||
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
||||||
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
|
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
|
||||||
del_timer(&dch->dbusytimer);
|
del_timer(&dch->dbusytimer);
|
||||||
#if 0
|
#ifdef FIXME
|
||||||
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
||||||
dchannel_sched_event(&hc->dch, D_CLEARBUSY);
|
dchannel_sched_event(&hc->dch, D_CLEARBUSY);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1884,12 +1850,13 @@ hfcpci_l2l1(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||||
hh = mISDN_HEAD_P(skb);
|
hh = mISDN_HEAD_P(skb);
|
||||||
if ((hh->prim == PH_DATA_REQ) ||
|
if ((hh->prim == PH_DATA_REQ) ||
|
||||||
(hh->prim == (DL_DATA | REQUEST))) {
|
(hh->prim == (DL_DATA | REQUEST))) {
|
||||||
#warning TODO: hier muss abgefragt werden, ob skb->len <= 0 ist, und ggf. ein -EINVAL zurückliefern, sonst wird zwar einmal confirmed, aber es regt sich nichts mehr. dies bitte auch für den d-kanal überdenken, sowie für alle andere kartentreiber.
|
|
||||||
if (bch->next_skb) {
|
if (bch->next_skb) {
|
||||||
printk(KERN_WARNING "%s: next_skb exist ERROR\n",
|
printk(KERN_WARNING "%s: next_skb exist ERROR\n",
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
return(-EBUSY);
|
return(-EBUSY);
|
||||||
}
|
}
|
||||||
|
if (skb->len <= 0)
|
||||||
|
return(-EINVAL);
|
||||||
bch->inst.lock(hc, 0);
|
bch->inst.lock(hc, 0);
|
||||||
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
|
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
|
||||||
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include "dchannel.h"
|
#include "dchannel.h"
|
||||||
#include "bchannel.h"
|
#include "bchannel.h"
|
||||||
#include "layer1.h"
|
#include "layer1.h"
|
||||||
#include "helper.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "hw_lock.h"
|
#include "hw_lock.h"
|
||||||
#include "hfcs_usb.h"
|
#include "hfcs_usb.h"
|
||||||
|
@ -221,8 +220,8 @@ static struct usb_device_id hfcsusb_idtab[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* some function prototypes */
|
/* some function prototypes */
|
||||||
static int hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb);
|
static int hfcsusb_l1hwD(mISDNinstance_t *inst, struct sk_buff *skb);
|
||||||
static int hfcsusb_l2l1B(mISDNif_t * hif, struct sk_buff *skb);
|
static int hfcsusb_l2l1B(mISDNinstance_t *inst, struct sk_buff *skb);
|
||||||
static int mode_bchannel(bchannel_t * bch, int bc, int protocol);
|
static int mode_bchannel(bchannel_t * bch, int bc, int protocol);
|
||||||
static void hfcsusb_ph_command(hfcsusb_t * card, u_char command);
|
static void hfcsusb_ph_command(hfcsusb_t * card, u_char command);
|
||||||
|
|
||||||
|
@ -433,32 +432,18 @@ hfcsusb_manager(void *data, u_int prim, void *arg)
|
||||||
&inst->st->para);
|
&inst->st->para);
|
||||||
break;
|
break;
|
||||||
case MGR_UNREGLAYER | REQUEST:
|
case MGR_UNREGLAYER | REQUEST:
|
||||||
|
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
||||||
|
HW_DEACTIVATE, 0, NULL, 0))) {
|
||||||
if (channel == 2) {
|
if (channel == 2) {
|
||||||
inst->down.fdata = &card->dch;
|
if (hfcsusb_l1hwD(inst, skb))
|
||||||
if ((skb =
|
|
||||||
create_link_skb(PH_CONTROL | REQUEST,
|
|
||||||
HW_DEACTIVATE, 0,
|
|
||||||
NULL, 0))) {
|
|
||||||
if (hfcsusb_l1hwD
|
|
||||||
(&inst->down, skb))
|
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
inst->down.fdata = &card->bch[channel];
|
if (hfcsusb_l2l1B(inst, skb))
|
||||||
if ((skb =
|
|
||||||
create_link_skb(MGR_DISCONNECT |
|
|
||||||
REQUEST, 0, 0, NULL,
|
|
||||||
0))) {
|
|
||||||
if (hfcsusb_l2l1B
|
|
||||||
(&inst->down, skb))
|
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
hw_mISDNObj.ctrl(inst->up.peer,
|
printk(KERN_WARNING "no SKB in %s MGR_UNREGLAYER | REQUEST\n", __FUNCTION__);
|
||||||
MGR_DISCONNECT | REQUEST,
|
hw_mISDNObj.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||||
&inst->up);
|
|
||||||
hw_mISDNObj.ctrl(inst, MGR_UNREGLAYER | REQUEST,
|
|
||||||
NULL);
|
|
||||||
break;
|
break;
|
||||||
case MGR_CLRSTPARA | INDICATION:
|
case MGR_CLRSTPARA | INDICATION:
|
||||||
arg = NULL;
|
arg = NULL;
|
||||||
|
@ -481,40 +466,18 @@ hfcsusb_manager(void *data, u_int prim, void *arg)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
case MGR_CONNECT | REQUEST:
|
|
||||||
return (mISDN_ConnectIF(inst, arg));
|
|
||||||
case MGR_SETIF | REQUEST:
|
|
||||||
case MGR_SETIF | INDICATION:
|
|
||||||
if (channel == 2)
|
|
||||||
return (mISDN_SetIF
|
|
||||||
(inst, arg, prim, hfcsusb_l1hwD,
|
|
||||||
NULL, &card->dch));
|
|
||||||
else
|
|
||||||
return (mISDN_SetIF
|
|
||||||
(inst, arg, prim, hfcsusb_l2l1B,
|
|
||||||
NULL, &card->bch[channel]));
|
|
||||||
break;
|
|
||||||
case MGR_DISCONNECT | REQUEST:
|
|
||||||
case MGR_DISCONNECT | INDICATION:
|
|
||||||
return (mISDN_DisConnectIF(inst, arg));
|
|
||||||
case MGR_SETSTACK | INDICATION:
|
case MGR_SETSTACK | INDICATION:
|
||||||
if ((channel != 2) && (inst->pid.global == 2)) {
|
if ((channel != 2) && (inst->pid.global == 2)) {
|
||||||
inst->down.fdata = &card->bch[channel];
|
if ((skb = create_link_skb(PH_ACTIVATE | REQUEST,
|
||||||
if ((skb =
|
|
||||||
create_link_skb(PH_ACTIVATE | REQUEST,
|
|
||||||
0, 0, NULL, 0))) {
|
0, 0, NULL, 0))) {
|
||||||
if (hfcsusb_l2l1B
|
if (hfcsusb_l2l1B(inst, skb))
|
||||||
(&inst->down, skb))
|
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
}
|
}
|
||||||
if (inst->pid.protocol[2] ==
|
if (inst->pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
||||||
ISDN_PID_L2_B_TRANS)
|
mISDN_queue_data(inst, FLG_MSG_UP, DL_ESTABLISH | INDICATION,
|
||||||
if_link(&inst->up,
|
|
||||||
DL_ESTABLISH | INDICATION,
|
|
||||||
0, 0, NULL, 0);
|
0, 0, NULL, 0);
|
||||||
else
|
else
|
||||||
if_link(&inst->up,
|
mISDN_queue_data(inst, FLG_MSG_UP, PH_ACTIVATE | INDICATION,
|
||||||
PH_ACTIVATE | INDICATION,
|
|
||||||
0, 0, NULL, 0);
|
0, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -547,11 +510,7 @@ S0_new_state(dchannel_t * dch)
|
||||||
{
|
{
|
||||||
u_int prim = PH_SIGNAL | INDICATION;
|
u_int prim = PH_SIGNAL | INDICATION;
|
||||||
u_int para = 0;
|
u_int para = 0;
|
||||||
mISDNif_t *upif = &dch->inst.up;
|
hfcsusb_t *card = dch->inst.privat;
|
||||||
hfcsusb_t *card = dch->hw;
|
|
||||||
|
|
||||||
if (!test_and_clear_bit(D_L1STATECHANGE, &dch->event))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (card->hw_mode & HW_MODE_TE) {
|
if (card->hw_mode & HW_MODE_TE) {
|
||||||
if (dch->debug)
|
if (dch->debug)
|
||||||
|
@ -589,7 +548,7 @@ S0_new_state(dchannel_t * dch)
|
||||||
"%s: NT %d",
|
"%s: NT %d",
|
||||||
__FUNCTION__, dch->ph_state);
|
__FUNCTION__, dch->ph_state);
|
||||||
|
|
||||||
dch->inst.lock(dch->inst.data, 0);
|
dch->inst.lock(dch->inst.privat, 0);
|
||||||
switch (dch->ph_state) {
|
switch (dch->ph_state) {
|
||||||
case (1):
|
case (1):
|
||||||
card->nt_timer = 0;
|
card->nt_timer = 0;
|
||||||
|
@ -610,8 +569,8 @@ S0_new_state(dchannel_t * dch)
|
||||||
/* allow G2 -> G3 transition */
|
/* allow G2 -> G3 transition */
|
||||||
queued_Write_hfc(card, HFCUSB_STATES, 2 | HFCUSB_NT_G2_G3);
|
queued_Write_hfc(card, HFCUSB_STATES, 2 | HFCUSB_NT_G2_G3);
|
||||||
}
|
}
|
||||||
upif = NULL;
|
dch->inst.unlock(dch->inst.privat);
|
||||||
break;
|
return;
|
||||||
case (3):
|
case (3):
|
||||||
card->nt_timer = 0;
|
card->nt_timer = 0;
|
||||||
card->hw_mode &= ~NT_ACTIVATION_TIMER;
|
card->hw_mode &= ~NT_ACTIVATION_TIMER;
|
||||||
|
@ -622,18 +581,14 @@ S0_new_state(dchannel_t * dch)
|
||||||
case (4):
|
case (4):
|
||||||
card->nt_timer = 0;
|
card->nt_timer = 0;
|
||||||
card->hw_mode &= ~NT_ACTIVATION_TIMER;
|
card->hw_mode &= ~NT_ACTIVATION_TIMER;
|
||||||
upif = NULL;
|
dch->inst.unlock(dch->inst.privat);
|
||||||
break;
|
return;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dch->inst.unlock(dch->inst.data);
|
dch->inst.unlock(dch->inst.privat);
|
||||||
}
|
|
||||||
|
|
||||||
while (upif) {
|
|
||||||
if_link(upif, prim, para, 0, NULL, 0);
|
|
||||||
upif = upif->clone;
|
|
||||||
}
|
}
|
||||||
|
mISDN_queue_data(&dch->inst, FLG_MSG_UP, prim, para, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************/
|
/******************************/
|
||||||
|
@ -647,7 +602,7 @@ state_handler(hfcsusb_t * card, __u8 new_l1_state)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
card->dch.ph_state = new_l1_state;
|
card->dch.ph_state = new_l1_state;
|
||||||
dchannel_sched_event(&card->dch, D_L1STATECHANGE);
|
S0_new_state(&card->dch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -668,7 +623,7 @@ mode_bchannel(bchannel_t * bch, int bc, int protocol)
|
||||||
{
|
{
|
||||||
__u8 conhdlc, sctrl, sctrl_r; /* conatainer for new register vals */
|
__u8 conhdlc, sctrl, sctrl_r; /* conatainer for new register vals */
|
||||||
|
|
||||||
hfcsusb_t *card = bch->inst.data;
|
hfcsusb_t *card = bch->inst.privat;
|
||||||
|
|
||||||
if (bch->debug & L1_DEB_HSCX)
|
if (bch->debug & L1_DEB_HSCX)
|
||||||
mISDN_debugprint(&bch->inst,
|
mISDN_debugprint(&bch->inst,
|
||||||
|
@ -744,10 +699,6 @@ mode_bchannel(bchannel_t * bch, int bc, int protocol)
|
||||||
|
|
||||||
if (protocol > ISDN_PID_NONE) {
|
if (protocol > ISDN_PID_NONE) {
|
||||||
handle_led(card, ((bch->channel)?LED_B2_ON:LED_B1_ON));
|
handle_led(card, ((bch->channel)?LED_B2_ON:LED_B1_ON));
|
||||||
|
|
||||||
/* signal the channel has space for transmit data */
|
|
||||||
bch_sched_event(bch, B_XMTBUFREADY);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
handle_led(card, ((bch->channel)?LED_B2_OFF:LED_B1_OFF));
|
handle_led(card, ((bch->channel)?LED_B2_OFF:LED_B1_OFF));
|
||||||
}
|
}
|
||||||
|
@ -814,19 +765,16 @@ hfcsusb_ph_command(hfcsusb_t * card, u_char command)
|
||||||
/* Layer 1 D-channel hardware access */
|
/* Layer 1 D-channel hardware access */
|
||||||
/*************************************/
|
/*************************************/
|
||||||
static int
|
static int
|
||||||
hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
hfcsusb_l1hwD(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
dchannel_t *dch;;
|
dchannel_t *dch;
|
||||||
int ret = -EINVAL;
|
int ret = 0;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh;
|
||||||
hfcsusb_t *card;
|
hfcsusb_t *card;
|
||||||
|
|
||||||
if (!hif || !skb)
|
|
||||||
return (ret);
|
|
||||||
hh = mISDN_HEAD_P(skb);
|
hh = mISDN_HEAD_P(skb);
|
||||||
dch = hif->fdata;
|
dch = container_of(inst, dchannel_t, inst);
|
||||||
card = dch->hw;
|
card = inst->privat;
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
if (hh->prim == PH_DATA_REQ) {
|
if (hh->prim == PH_DATA_REQ) {
|
||||||
if (dch->next_skb) {
|
if (dch->next_skb) {
|
||||||
|
@ -834,11 +782,11 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
||||||
"hfcsusb l2l1 next_skb exist this shouldn't happen");
|
"hfcsusb l2l1 next_skb exist this shouldn't happen");
|
||||||
return (-EBUSY);
|
return (-EBUSY);
|
||||||
}
|
}
|
||||||
dch->inst.lock(dch->inst.data, 0);
|
dch->inst.lock(dch->inst.privat, 0);
|
||||||
if (test_and_set_bit(FLG_TX_BUSY, &dch->DFlags)) {
|
if (test_and_set_bit(FLG_TX_BUSY, &dch->DFlags)) {
|
||||||
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
|
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
dch->next_skb = skb;
|
dch->next_skb = skb;
|
||||||
dch->inst.unlock(dch->inst.data);
|
dch->inst.unlock(dch->inst.privat);
|
||||||
return (0);
|
return (0);
|
||||||
} else {
|
} else {
|
||||||
/* prepare buffer, which is transmitted by
|
/* prepare buffer, which is transmitted by
|
||||||
|
@ -846,22 +794,23 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
||||||
dch->tx_len = skb->len;
|
dch->tx_len = skb->len;
|
||||||
memcpy(dch->tx_buf, skb->data, dch->tx_len);
|
memcpy(dch->tx_buf, skb->data, dch->tx_len);
|
||||||
dch->tx_idx = 0;
|
dch->tx_idx = 0;
|
||||||
dch->inst.unlock(dch->inst.data);
|
dch->inst.unlock(dch->inst.privat);
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
return (if_newhead(&dch->inst.up, PH_DATA_CNF,
|
return(mISDN_queueup_newhead(inst, 0, PH_DATA_CNF,
|
||||||
hh->dinfo, skb));
|
hh->dinfo, skb));
|
||||||
}
|
}
|
||||||
} else if (hh->prim == (PH_SIGNAL | REQUEST)) {
|
} else if (hh->prim == (PH_SIGNAL | REQUEST)) {
|
||||||
dch->inst.lock(dch->inst.data, 0);
|
dch->inst.lock(dch->inst.privat, 0);
|
||||||
if (hh->dinfo == INFO3_P8)
|
if (hh->dinfo == INFO3_P8)
|
||||||
hfcsusb_ph_command(dch->hw, S0_L1CMD_AR8);
|
hfcsusb_ph_command(dch->hw, S0_L1CMD_AR8);
|
||||||
else if (hh->dinfo == INFO3_P10)
|
else if (hh->dinfo == INFO3_P10)
|
||||||
hfcsusb_ph_command(dch->hw, S0_L1CMD_AR10);
|
hfcsusb_ph_command(dch->hw, S0_L1CMD_AR10);
|
||||||
else
|
else
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
dch->inst.unlock(dch->inst.data);
|
|
||||||
|
dch->inst.unlock(dch->inst.privat);
|
||||||
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
||||||
dch->inst.lock(dch->inst.data, 0);
|
dch->inst.lock(dch->inst.privat, 0);
|
||||||
if (hh->dinfo == HW_RESET) {
|
if (hh->dinfo == HW_RESET) {
|
||||||
if (dch->ph_state != 0)
|
if (dch->ph_state != 0)
|
||||||
hfcsusb_ph_command(dch->hw,
|
hfcsusb_ph_command(dch->hw,
|
||||||
|
@ -870,15 +819,16 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
||||||
} else if (hh->dinfo == HW_POWERUP) {
|
} else if (hh->dinfo == HW_POWERUP) {
|
||||||
hfcsusb_ph_command(dch->hw, S0_L1CMD_ECK);
|
hfcsusb_ph_command(dch->hw, S0_L1CMD_ECK);
|
||||||
} else if (hh->dinfo == HW_DEACTIVATE) {
|
} else if (hh->dinfo == HW_DEACTIVATE) {
|
||||||
discard_queue(&dch->rqueue);
|
|
||||||
if (dch->next_skb) {
|
if (dch->next_skb) {
|
||||||
dev_kfree_skb(dch->next_skb);
|
dev_kfree_skb(dch->next_skb);
|
||||||
dch->next_skb = NULL;
|
dch->next_skb = NULL;
|
||||||
}
|
}
|
||||||
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
||||||
|
#ifdef FIXME
|
||||||
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
||||||
dchannel_sched_event(dch, D_CLEARBUSY);
|
dchannel_sched_event(dch, D_CLEARBUSY);
|
||||||
|
#endif
|
||||||
} else if ((hh->dinfo & HW_TESTLOOP) == HW_TESTLOOP) {
|
} else if ((hh->dinfo & HW_TESTLOOP) == HW_TESTLOOP) {
|
||||||
u_char val = 0;
|
u_char val = 0;
|
||||||
|
|
||||||
|
@ -894,9 +844,9 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
||||||
hh->dinfo);
|
hh->dinfo);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
dch->inst.unlock(dch->inst.data);
|
dch->inst.unlock(dch->inst.privat);
|
||||||
} else if (hh->prim == (PH_ACTIVATE | REQUEST)) {
|
} else if (hh->prim == (PH_ACTIVATE | REQUEST)) {
|
||||||
dch->inst.lock(dch->inst.data, 0);
|
dch->inst.lock(dch->inst.privat, 0);
|
||||||
if (card->hw_mode & HW_MODE_NT) {
|
if (card->hw_mode & HW_MODE_NT) {
|
||||||
hfcsusb_ph_command(dch->hw, HFC_L1_ACTIVATE_NT);
|
hfcsusb_ph_command(dch->hw, HFC_L1_ACTIVATE_NT);
|
||||||
} else {
|
} else {
|
||||||
|
@ -905,9 +855,9 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
dch->inst.unlock(dch->inst.data);
|
dch->inst.unlock(dch->inst.privat);
|
||||||
} else if (hh->prim == (PH_DEACTIVATE | REQUEST)) {
|
} else if (hh->prim == (PH_DEACTIVATE | REQUEST)) {
|
||||||
dch->inst.lock(dch->inst.data, 0);
|
dch->inst.lock(dch->inst.privat, 0);
|
||||||
if (card->hw_mode & HW_MODE_NT) {
|
if (card->hw_mode & HW_MODE_NT) {
|
||||||
hfcsusb_ph_command(dch->hw, HFC_L1_DEACTIVATE_NT);
|
hfcsusb_ph_command(dch->hw, HFC_L1_DEACTIVATE_NT);
|
||||||
} else {
|
} else {
|
||||||
|
@ -916,7 +866,7 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
dch->inst.unlock(dch->inst.data);
|
dch->inst.unlock(dch->inst.privat);
|
||||||
} else {
|
} else {
|
||||||
if (dch->debug & L1_DEB_WARN)
|
if (dch->debug & L1_DEB_WARN)
|
||||||
mISDN_debugprint(&dch->inst,
|
mISDN_debugprint(&dch->inst,
|
||||||
|
@ -933,20 +883,11 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
||||||
/* Layer2 -> Layer 1 Transfer */
|
/* Layer2 -> Layer 1 Transfer */
|
||||||
/******************************/
|
/******************************/
|
||||||
static int
|
static int
|
||||||
hfcsusb_l2l1B(mISDNif_t * hif, struct sk_buff *skb)
|
hfcsusb_l2l1B(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
bchannel_t *bch;
|
bchannel_t *bch = container_of(inst, bchannel_t, inst);
|
||||||
int ret = -EINVAL;
|
int ret = 0;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||||
|
|
||||||
hfcsusb_t *card;
|
|
||||||
|
|
||||||
if (!hif || !skb)
|
|
||||||
return (ret);
|
|
||||||
hh = mISDN_HEAD_P(skb);
|
|
||||||
bch = hif->fdata;
|
|
||||||
|
|
||||||
card = bch->hw;
|
|
||||||
|
|
||||||
if ((hh->prim == PH_DATA_REQ) || (hh->prim == (DL_DATA | REQUEST))) {
|
if ((hh->prim == PH_DATA_REQ) || (hh->prim == (DL_DATA | REQUEST))) {
|
||||||
if (bch->next_skb) {
|
if (bch->next_skb) {
|
||||||
|
@ -954,11 +895,13 @@ hfcsusb_l2l1B(mISDNif_t * hif, struct sk_buff *skb)
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
return (-EBUSY);
|
return (-EBUSY);
|
||||||
}
|
}
|
||||||
bch->inst.lock(bch->inst.data, 0);
|
if (skb->len <= 0)
|
||||||
|
return(-EINVAL);
|
||||||
|
bch->inst.lock(bch->inst.privat, 0);
|
||||||
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
|
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
|
||||||
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
bch->next_skb = skb;
|
bch->next_skb = skb;
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
return (0);
|
return (0);
|
||||||
} else {
|
} else {
|
||||||
/* prepare buffer, wich is transmitted by
|
/* prepare buffer, wich is transmitted by
|
||||||
|
@ -966,40 +909,39 @@ hfcsusb_l2l1B(mISDNif_t * hif, struct sk_buff *skb)
|
||||||
bch->tx_len = skb->len;
|
bch->tx_len = skb->len;
|
||||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||||
bch->tx_idx = 0;
|
bch->tx_idx = 0;
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
if ((bch->inst.pid.protocol[2] ==
|
#ifdef FIXME
|
||||||
ISDN_PID_L2_B_RAWDEV)
|
if ((bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
||||||
&& bch->dev)
|
&& bch->dev)
|
||||||
hif = &bch->dev->rport.pif;
|
hif = &bch->dev->rport.pif;
|
||||||
else
|
else
|
||||||
hif = &bch->inst.up;
|
hif = &bch->inst.up;
|
||||||
|
#endif
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
return (if_newhead(hif, hh->prim | CONFIRM,
|
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM,
|
||||||
hh->dinfo, skb));
|
hh->dinfo, skb));
|
||||||
}
|
}
|
||||||
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
|
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
|
||||||
(hh->prim == (DL_ESTABLISH | REQUEST))) {
|
(hh->prim == (DL_ESTABLISH | REQUEST))) {
|
||||||
if (test_and_set_bit(BC_FLG_ACTIV, &bch->Flag))
|
if (!test_and_set_bit(BC_FLG_ACTIV, &bch->Flag)) {
|
||||||
ret = 0;
|
bch->inst.lock(bch->inst.privat, 0);
|
||||||
else {
|
ret = mode_bchannel(bch, bch->channel,
|
||||||
bch->inst.lock(bch->inst.data, 0);
|
|
||||||
ret =
|
|
||||||
mode_bchannel(bch, bch->channel,
|
|
||||||
bch->inst.pid.protocol[1]);
|
bch->inst.pid.protocol[1]);
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
}
|
}
|
||||||
|
#ifdef FIXME
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
||||||
if (bch->dev)
|
if (bch->dev)
|
||||||
if_link(&bch->dev->rport.pif,
|
if_link(&bch->dev->rport.pif,
|
||||||
hh->prim | CONFIRM, 0, 0, NULL, 0);
|
hh->prim | CONFIRM, 0, 0, NULL, 0);
|
||||||
|
#endif
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
return (if_newhead
|
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, ret, skb));
|
||||||
(&bch->inst.up, hh->prim | CONFIRM, ret, skb));
|
} else if ((hh->prim == (PH_DEACTIVATE | REQUEST)) ||
|
||||||
} else if ((hh->prim == (PH_DEACTIVATE | REQUEST))
|
(hh->prim == (DL_RELEASE | REQUEST)) ||
|
||||||
|| (hh->prim == (DL_RELEASE | REQUEST))
|
((hh->prim == (PH_CONTROL | REQUEST) && (hh->dinfo == HW_DEACTIVATE)))) {
|
||||||
|| (hh->prim == (MGR_DISCONNECT | REQUEST))) {
|
|
||||||
|
|
||||||
bch->inst.lock(bch->inst.data, 0);
|
bch->inst.lock(bch->inst.privat, 0);
|
||||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||||
dev_kfree_skb(bch->next_skb);
|
dev_kfree_skb(bch->next_skb);
|
||||||
bch->next_skb = NULL;
|
bch->next_skb = NULL;
|
||||||
|
@ -1007,26 +949,25 @@ hfcsusb_l2l1B(mISDNif_t * hif, struct sk_buff *skb)
|
||||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||||
mode_bchannel(bch, bch->channel, ISDN_PID_NONE);
|
mode_bchannel(bch, bch->channel, ISDN_PID_NONE);
|
||||||
test_and_clear_bit(BC_FLG_ACTIV, &bch->Flag);
|
test_and_clear_bit(BC_FLG_ACTIV, &bch->Flag);
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
if (hh->prim != (MGR_DISCONNECT | REQUEST)) {
|
if (hh->prim != (PH_CONTROL | REQUEST)) {
|
||||||
if (bch->inst.pid.protocol[2] ==
|
#ifdef FIXME
|
||||||
ISDN_PID_L2_B_RAWDEV)
|
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
||||||
if (bch->dev)
|
if (bch->dev)
|
||||||
if_link(&bch->dev->rport.pif,
|
if_link(&bch->dev->rport.pif,
|
||||||
hh->prim | CONFIRM, 0, 0,
|
hh->prim | CONFIRM, 0, 0, NULL, 0);
|
||||||
NULL, 0);
|
#endif
|
||||||
if (!if_newhead
|
if (!mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, 0, skb))
|
||||||
(&bch->inst.up, hh->prim | CONFIRM, 0, skb))
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
||||||
// do not handle PH_CONTROL | REQUEST ??
|
// do not handle PH_CONTROL | REQUEST ??
|
||||||
|
ret = -EINVAL;
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "%s: unknown prim(%x)\n",
|
printk(KERN_WARNING "%s: unknown prim(%x)\n",
|
||||||
__FUNCTION__, hh->prim);
|
__FUNCTION__, hh->prim);
|
||||||
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
if (!ret)
|
if (!ret)
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
|
@ -1083,23 +1024,15 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
|
||||||
if (card->bch[fifo->bch_idx].protocol == ISDN_PID_L1_B_64TRANS) {
|
if (card->bch[fifo->bch_idx].protocol == ISDN_PID_L1_B_64TRANS) {
|
||||||
if (fifo->skbuff->len >= 128) {
|
if (fifo->skbuff->len >= 128) {
|
||||||
if (!(skb = alloc_stack_skb(fifo->skbuff->len,
|
if (!(skb = alloc_stack_skb(fifo->skbuff->len,
|
||||||
card->bch->up_headerlen)))
|
card->bch[fifo->bch_idx].up_headerlen)))
|
||||||
printk(KERN_WARNING "HFC-S USB: receive out of memory\n");
|
printk(KERN_WARNING "HFC-S USB: receive out of memory\n");
|
||||||
else {
|
else {
|
||||||
ptr =
|
ptr = skb_put(skb, fifo->skbuff->len);
|
||||||
skb_put(skb,
|
memcpy(ptr, fifo->skbuff->data, fifo->skbuff->len);
|
||||||
fifo->skbuff->
|
|
||||||
len);
|
|
||||||
memcpy(ptr, fifo->skbuff->data,
|
|
||||||
fifo->skbuff->len);
|
|
||||||
dev_kfree_skb(fifo->skbuff);
|
dev_kfree_skb(fifo->skbuff);
|
||||||
fifo->skbuff=NULL;
|
fifo->skbuff=NULL;
|
||||||
|
queue_bch_frame(&card->bch[fifo->bch_idx],
|
||||||
skb_queue_tail(&card->bch[fifo->bch_idx].
|
INDICATION, MISDN_ID_ANY, skb);
|
||||||
rqueue,
|
|
||||||
skb);
|
|
||||||
|
|
||||||
bch_sched_event(&card->bch[fifo->bch_idx], B_RCVBUFREADY);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -1115,28 +1048,15 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
|
||||||
|
|
||||||
switch (fifon) {
|
switch (fifon) {
|
||||||
case HFCUSB_D_RX:
|
case HFCUSB_D_RX:
|
||||||
if ((skb =
|
if ((skb = alloc_stack_skb(fifo->skbuff->len,
|
||||||
alloc_stack_skb(fifo->skbuff->
|
card->dch.up_headerlen))) {
|
||||||
len,
|
ptr = skb_put(skb, fifo->skbuff->len);
|
||||||
card->dch.
|
memcpy(ptr, fifo->skbuff->data,
|
||||||
up_headerlen)))
|
fifo->skbuff->len);
|
||||||
{
|
|
||||||
ptr =
|
|
||||||
skb_put(skb,
|
|
||||||
fifo->skbuff->
|
|
||||||
len);
|
|
||||||
memcpy(ptr, fifo->skbuff->data, fifo->skbuff->len);
|
|
||||||
dev_kfree_skb(fifo->skbuff);
|
dev_kfree_skb(fifo->skbuff);
|
||||||
fifo->skbuff=NULL;
|
fifo->skbuff=NULL;
|
||||||
|
mISDN_queueup_newhead(&card->dch.inst, 0,
|
||||||
skb_queue_tail(&card->dch.
|
PH_DATA_IND, MISDN_ID_ANY, skb);
|
||||||
rqueue,
|
|
||||||
skb);
|
|
||||||
|
|
||||||
dchannel_sched_event
|
|
||||||
(&card->dch,
|
|
||||||
D_RCVBUFREADY);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"HFC-S USB: D receive out of memory\n");
|
"HFC-S USB: D receive out of memory\n");
|
||||||
|
@ -1145,30 +1065,15 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
|
||||||
case HFCUSB_B1_RX:
|
case HFCUSB_B1_RX:
|
||||||
case HFCUSB_B2_RX:
|
case HFCUSB_B2_RX:
|
||||||
if (card->bch[fifo->bch_idx].protocol > ISDN_PID_NONE) {
|
if (card->bch[fifo->bch_idx].protocol > ISDN_PID_NONE) {
|
||||||
if ((skb =
|
if ((skb = alloc_stack_skb(fifo->skbuff->len,
|
||||||
alloc_stack_skb(fifo->skbuff->
|
card->bch[fifo->bch_idx].up_headerlen)))
|
||||||
len,
|
|
||||||
card->
|
|
||||||
bch[fifo->bch_idx].
|
|
||||||
up_headerlen)))
|
|
||||||
{
|
{
|
||||||
ptr =
|
ptr = skb_put(skb, fifo->skbuff->len);
|
||||||
skb_put(skb,
|
|
||||||
fifo->skbuff->
|
|
||||||
len);
|
|
||||||
memcpy(ptr, fifo->skbuff->data, fifo->skbuff->len);
|
memcpy(ptr, fifo->skbuff->data, fifo->skbuff->len);
|
||||||
dev_kfree_skb(fifo->skbuff);
|
dev_kfree_skb(fifo->skbuff);
|
||||||
fifo->skbuff=NULL;
|
fifo->skbuff=NULL;
|
||||||
|
queue_bch_frame(&card->bch[fifo->bch_idx],
|
||||||
skb_queue_tail(&card->
|
INDICATION, MISDN_ID_ANY, skb);
|
||||||
bch
|
|
||||||
[fifo->bch_idx].
|
|
||||||
rqueue,
|
|
||||||
skb);
|
|
||||||
bch_sched_event(&card->
|
|
||||||
bch
|
|
||||||
[fifo->bch_idx],
|
|
||||||
B_RCVBUFREADY);
|
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"HFC-S USB: B%i receive out of memory\n",
|
"HFC-S USB: B%i receive out of memory\n",
|
||||||
|
@ -1372,16 +1277,22 @@ rx_int_complete(struct urb *urb, struct pt_regs *regs)
|
||||||
void
|
void
|
||||||
next_d_tx_frame(hfcsusb_t * card)
|
next_d_tx_frame(hfcsusb_t * card)
|
||||||
{
|
{
|
||||||
if (test_and_clear_bit(FLG_TX_NEXT, &card->dch.DFlags)) {
|
if (test_bit(FLG_TX_NEXT, &card->dch.DFlags)) {
|
||||||
if (card->dch.next_skb) {
|
struct sk_buff *skb = card->dch.next_skb;
|
||||||
card->dch.tx_len = card->dch.next_skb->len;
|
if (skb) {
|
||||||
memcpy(card->dch.tx_buf,
|
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||||
card->dch.next_skb->data, card->dch.tx_len);
|
|
||||||
|
card->dch.next_skb = NULL;
|
||||||
|
test_and_clear_bit(FLG_TX_NEXT, &card->dch.DFlags);
|
||||||
|
card->dch.tx_len = skb->len;
|
||||||
|
memcpy(card->dch.tx_buf, skb->data, card->dch.tx_len);
|
||||||
card->dch.tx_idx = 0;
|
card->dch.tx_idx = 0;
|
||||||
dchannel_sched_event(&card->dch, D_XMTBUFREADY);
|
if (mISDN_queueup_newhead(&card->dch.inst, 0, PH_DATA_CNF, hh->dinfo, skb))
|
||||||
|
dev_kfree_skb(skb);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"hfcd tx irq TX_NEXT without skb\n");
|
"hfcd tx irq TX_NEXT without skb\n");
|
||||||
|
test_and_clear_bit(FLG_TX_NEXT, &card->dch.DFlags);
|
||||||
test_and_clear_bit(FLG_TX_BUSY, &card->dch.DFlags);
|
test_and_clear_bit(FLG_TX_BUSY, &card->dch.DFlags);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -1391,20 +1302,23 @@ next_d_tx_frame(hfcsusb_t * card)
|
||||||
void
|
void
|
||||||
next_b_tx_frame(hfcsusb_t * card, __u8 bch_idx)
|
next_b_tx_frame(hfcsusb_t * card, __u8 bch_idx)
|
||||||
{
|
{
|
||||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &card->bch[bch_idx].Flag)) {
|
if (test_bit(BC_FLG_TX_NEXT, &card->bch[bch_idx].Flag)) {
|
||||||
if (card->bch[bch_idx].next_skb) {
|
struct sk_buff *skb = card->bch[bch_idx].next_skb;
|
||||||
|
if (skb) {
|
||||||
|
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||||
|
|
||||||
|
card->bch[bch_idx].next_skb = NULL;
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &card->bch[bch_idx].Flag);
|
||||||
card->bch[bch_idx].tx_idx = 0;
|
card->bch[bch_idx].tx_idx = 0;
|
||||||
card->bch[bch_idx].tx_len =
|
card->bch[bch_idx].tx_len = skb->len;
|
||||||
card->bch[bch_idx].next_skb->len;
|
memcpy(card->bch[bch_idx].tx_buf, skb->data, card->bch[bch_idx].tx_len);
|
||||||
memcpy(card->bch[bch_idx].tx_buf,
|
|
||||||
card->bch[bch_idx].next_skb->data,
|
queue_bch_frame(&card->bch[bch_idx], CONFIRM, hh->dinfo, skb);
|
||||||
card->bch[bch_idx].tx_len);
|
} else {
|
||||||
bch_sched_event(&card->bch[bch_idx],
|
|
||||||
B_XMTBUFREADY);
|
|
||||||
} else
|
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"hfc B%i tx irq TX_NEXT without skb\n",
|
"hfc B%i tx irq TX_NEXT without skb\n", bch_idx);
|
||||||
bch_idx);
|
test_and_clear_bit(BC_FLG_TX_NEXT, &card->bch[bch_idx].Flag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1572,7 +1486,7 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
|
||||||
if ((fifon == HFCUSB_D_TX) && (card->hw_mode & HW_MODE_NT)
|
if ((fifon == HFCUSB_D_TX) && (card->hw_mode & HW_MODE_NT)
|
||||||
&& (card->hw_mode & NT_ACTIVATION_TIMER)) {
|
&& (card->hw_mode & NT_ACTIVATION_TIMER)) {
|
||||||
if ((--card->nt_timer) < 0)
|
if ((--card->nt_timer) < 0)
|
||||||
dchannel_sched_event(&card->dch, D_L1STATECHANGE);
|
S0_new_state(&card->dch);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -1882,8 +1796,6 @@ release_card(hfcsusb_t * card)
|
||||||
mISDN_free_bch(&card->bch[1]);
|
mISDN_free_bch(&card->bch[1]);
|
||||||
mISDN_free_bch(&card->bch[0]);
|
mISDN_free_bch(&card->bch[0]);
|
||||||
mISDN_free_dch(&card->dch);
|
mISDN_free_dch(&card->dch);
|
||||||
hw_mISDNObj.ctrl(card->dch.inst.up.peer, MGR_DISCONNECT | REQUEST,
|
|
||||||
&card->dch.inst.up);
|
|
||||||
hw_mISDNObj.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
|
hw_mISDNObj.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||||
list_del(&card->list);
|
list_del(&card->list);
|
||||||
unlock_dev(card);
|
unlock_dev(card);
|
||||||
|
@ -1934,7 +1846,7 @@ setup_instance(hfcsusb_t * card)
|
||||||
card->dch.inst.unlock = unlock_dev;
|
card->dch.inst.unlock = unlock_dev;
|
||||||
card->dch.inst.pid.layermask = ISDN_LAYER(0);
|
card->dch.inst.pid.layermask = ISDN_LAYER(0);
|
||||||
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_TE_S0;
|
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_TE_S0;
|
||||||
mISDN_init_instance(&card->dch.inst, &hw_mISDNObj, card);
|
mISDN_init_instance(&card->dch.inst, &hw_mISDNObj, card, hfcsusb_l1hwD);
|
||||||
sprintf(card->dch.inst.name, "hfcsusb_%d", hfcsusb_cnt + 1);
|
sprintf(card->dch.inst.name, "hfcsusb_%d", hfcsusb_cnt + 1);
|
||||||
mISDN_set_dchannel_pid(&pid, protocol[hfcsusb_cnt],
|
mISDN_set_dchannel_pid(&pid, protocol[hfcsusb_cnt],
|
||||||
layermask[hfcsusb_cnt]);
|
layermask[hfcsusb_cnt]);
|
||||||
|
@ -1944,8 +1856,7 @@ setup_instance(hfcsusb_t * card)
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
card->bch[i].channel = i;
|
card->bch[i].channel = i;
|
||||||
mISDN_init_instance(&card->bch[i].inst, &hw_mISDNObj,
|
mISDN_init_instance(&card->bch[i].inst, &hw_mISDNObj, card, hfcsusb_l2l1B);
|
||||||
card);
|
|
||||||
card->bch[i].inst.pid.layermask = ISDN_LAYER(0);
|
card->bch[i].inst.pid.layermask = ISDN_LAYER(0);
|
||||||
card->bch[i].inst.lock = lock_dev;
|
card->bch[i].inst.lock = lock_dev;
|
||||||
card->bch[i].inst.unlock = unlock_dev;
|
card->bch[i].inst.unlock = unlock_dev;
|
||||||
|
@ -1954,10 +1865,12 @@ setup_instance(hfcsusb_t * card)
|
||||||
card->dch.inst.name, i + 1);
|
card->dch.inst.name, i + 1);
|
||||||
mISDN_init_bch(&card->bch[i]);
|
mISDN_init_bch(&card->bch[i]);
|
||||||
card->bch[i].hw = card;
|
card->bch[i].hw = card;
|
||||||
|
#ifdef FIXME
|
||||||
if (card->bch[i].dev) {
|
if (card->bch[i].dev) {
|
||||||
card->bch[i].dev->wport.pif.func = hfcsusb_l2l1B;
|
card->bch[i].dev->wport.pif.func = hfcsusb_l2l1B;
|
||||||
card->bch[i].dev->wport.pif.fdata = &card->bch[i];
|
card->bch[i].dev->wport.pif.fdata = &card->bch[i];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (protocol[hfcsusb_cnt] & 0x10) {
|
if (protocol[hfcsusb_cnt] & 0x10) {
|
||||||
|
|
|
@ -243,16 +243,16 @@ isac_xpr_irq(dchannel_t *dch)
|
||||||
if (dch->tx_idx < dch->tx_len) {
|
if (dch->tx_idx < dch->tx_len) {
|
||||||
isac_fill_fifo(dch);
|
isac_fill_fifo(dch);
|
||||||
} else {
|
} else {
|
||||||
if (test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
if (test_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb = dch->next_skb;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||||
if ((skb = dch->next_skb)) {
|
if (skb) {
|
||||||
dch->next_skb = NULL;
|
dch->next_skb = NULL;
|
||||||
|
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
dch->tx_len = skb->len;
|
dch->tx_len = skb->len;
|
||||||
memcpy(dch->tx_buf, skb->data, dch->tx_len);
|
memcpy(dch->tx_buf, skb->data, dch->tx_len);
|
||||||
dch->tx_idx = 0;
|
dch->tx_idx = 0;
|
||||||
isac_fill_fifo(dch);
|
isac_fill_fifo(dch);
|
||||||
hh = mISDN_HEAD_P(skb);
|
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
if (unlikely(mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_CNF, hh->dinfo, skb))) {
|
if (unlikely(mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_CNF, hh->dinfo, skb))) {
|
||||||
int_error();
|
int_error();
|
||||||
|
@ -260,6 +260,7 @@ isac_xpr_irq(dchannel_t *dch)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "isac tx irq TX_NEXT without skb\n");
|
printk(KERN_WARNING "isac tx irq TX_NEXT without skb\n");
|
||||||
|
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -283,11 +284,12 @@ isac_retransmit(dchannel_t *dch)
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "mISDN: ISAC XDU no TX_BUSY\n");
|
printk(KERN_WARNING "mISDN: ISAC XDU no TX_BUSY\n");
|
||||||
mISDN_debugprint(&dch->inst, "ISAC XDU no TX_BUSY");
|
mISDN_debugprint(&dch->inst, "ISAC XDU no TX_BUSY");
|
||||||
if (test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
if (test_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb = dch->next_skb;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||||
if ((skb = dch->next_skb)) {
|
if (skb) {
|
||||||
dch->next_skb = NULL;
|
dch->next_skb = NULL;
|
||||||
|
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
dch->tx_len = skb->len;
|
dch->tx_len = skb->len;
|
||||||
memcpy(dch->tx_buf, skb->data, dch->tx_len);
|
memcpy(dch->tx_buf, skb->data, dch->tx_len);
|
||||||
dch->tx_idx = 0;
|
dch->tx_idx = 0;
|
||||||
|
@ -300,6 +302,7 @@ isac_retransmit(dchannel_t *dch)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "isac xdu irq TX_NEXT without skb\n");
|
printk(KERN_WARNING "isac xdu irq TX_NEXT without skb\n");
|
||||||
|
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
|
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include "layer1.h"
|
#include "layer1.h"
|
||||||
#include "helper.h"
|
|
||||||
#include "bchannel.h"
|
#include "bchannel.h"
|
||||||
#include "isar.h"
|
#include "isar.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
@ -462,7 +461,6 @@ isar_rcv_frame(bchannel_t *bch)
|
||||||
{
|
{
|
||||||
u_char *ptr;
|
u_char *ptr;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
u_int pr;
|
|
||||||
isar_hw_t *ih = bch->hw;
|
isar_hw_t *ih = bch->hw;
|
||||||
|
|
||||||
if (!ih->reg->clsb) {
|
if (!ih->reg->clsb) {
|
||||||
|
@ -483,14 +481,7 @@ isar_rcv_frame(bchannel_t *bch)
|
||||||
case ISDN_PID_L1_B_MODEM_ASYNC:
|
case ISDN_PID_L1_B_MODEM_ASYNC:
|
||||||
if ((skb = alloc_stack_skb(ih->reg->clsb, bch->up_headerlen))) {
|
if ((skb = alloc_stack_skb(ih->reg->clsb, bch->up_headerlen))) {
|
||||||
rcv_mbox(bch, ih->reg, (u_char *)skb_put(skb, ih->reg->clsb));
|
rcv_mbox(bch, ih->reg, (u_char *)skb_put(skb, ih->reg->clsb));
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||||
pr = DL_DATA | INDICATION;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | INDICATION;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, MISDN_ID_ANY, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "mISDN: skb out of memory\n");
|
printk(KERN_WARNING "mISDN: skb out of memory\n");
|
||||||
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
|
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
|
||||||
|
@ -530,14 +521,7 @@ isar_rcv_frame(bchannel_t *bch)
|
||||||
} else {
|
} else {
|
||||||
memcpy(skb_put(skb, bch->rx_idx-2),
|
memcpy(skb_put(skb, bch->rx_idx-2),
|
||||||
bch->rx_buf, bch->rx_idx-2);
|
bch->rx_buf, bch->rx_idx-2);
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||||
pr = DL_DATA | INDICATION;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | INDICATION;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, MISDN_ID_ANY, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
bch->rx_idx = 0;
|
bch->rx_idx = 0;
|
||||||
}
|
}
|
||||||
|
@ -569,14 +553,7 @@ isar_rcv_frame(bchannel_t *bch)
|
||||||
ih->state = STFAX_ESCAPE;
|
ih->state = STFAX_ESCAPE;
|
||||||
// set_skb_flag(skb, DF_NOMOREDATA);
|
// set_skb_flag(skb, DF_NOMOREDATA);
|
||||||
}
|
}
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||||
pr = DL_DATA | INDICATION;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | INDICATION;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, MISDN_ID_ANY, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
if (ih->reg->cmsb & SART_NMD)
|
if (ih->reg->cmsb & SART_NMD)
|
||||||
deliver_status(bch, HW_MOD_NOCARR);
|
deliver_status(bch, HW_MOD_NOCARR);
|
||||||
} else {
|
} else {
|
||||||
|
@ -623,14 +600,7 @@ isar_rcv_frame(bchannel_t *bch)
|
||||||
// if (ih->reg->cmsb & SART_NMD)
|
// if (ih->reg->cmsb & SART_NMD)
|
||||||
/* ABORT */
|
/* ABORT */
|
||||||
// set_skb_flag(skb, DF_NOMOREDATA);
|
// set_skb_flag(skb, DF_NOMOREDATA);
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||||
pr = DL_DATA | INDICATION;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | INDICATION;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, MISDN_ID_ANY, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
bch->rx_idx = 0;
|
bch->rx_idx = 0;
|
||||||
}
|
}
|
||||||
|
@ -772,29 +742,23 @@ send_frames(bchannel_t *bch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
if (test_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||||
struct sk_buff *skb = bch->next_skb;
|
struct sk_buff *skb = bch->next_skb;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh;
|
||||||
u_int pr;
|
|
||||||
if (skb) {
|
if (skb) {
|
||||||
bch->next_skb = NULL;
|
bch->next_skb = NULL;
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
hh = mISDN_HEAD_P(skb);
|
hh = mISDN_HEAD_P(skb);
|
||||||
bch->tx_idx = 0;
|
bch->tx_idx = 0;
|
||||||
bch->tx_len = skb->len;
|
bch->tx_len = skb->len;
|
||||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||||
isar_fill_fifo(bch);
|
isar_fill_fifo(bch);
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||||
pr = DL_DATA | CONFIRM;
|
|
||||||
else
|
|
||||||
pr = PH_DATA | CONFIRM;
|
|
||||||
if (unlikely(mISDN_queueup_newhead(&bch->inst, 0, pr, hh->dinfo, skb))) {
|
|
||||||
int_error();
|
|
||||||
dev_kfree_skb(skb);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
bch->tx_len = 0;
|
bch->tx_len = 0;
|
||||||
printk(KERN_WARNING "isar tx irq TX_NEXT without skb\n");
|
printk(KERN_WARNING "isar tx irq TX_NEXT without skb\n");
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1597,18 +1561,19 @@ int
|
||||||
isar_down(mISDNinstance_t *inst, struct sk_buff *skb)
|
isar_down(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
bchannel_t *bch;
|
bchannel_t *bch;
|
||||||
int ret = -EINVAL;
|
int ret = 0;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh;
|
||||||
|
|
||||||
hh = mISDN_HEAD_P(skb);
|
hh = mISDN_HEAD_P(skb);
|
||||||
bch = container_of(inst, bchannel_t, inst);
|
bch = container_of(inst, bchannel_t, inst);
|
||||||
ret = 0;
|
|
||||||
if ((hh->prim == PH_DATA_REQ) ||
|
if ((hh->prim == PH_DATA_REQ) ||
|
||||||
(hh->prim == (DL_DATA | REQUEST))) {
|
(hh->prim == (DL_DATA | REQUEST))) {
|
||||||
if (bch->next_skb) {
|
if (bch->next_skb) {
|
||||||
mISDN_debugprint(&bch->inst, " l2l1 next_skb exist this shouldn't happen");
|
mISDN_debugprint(&bch->inst, " l2l1 next_skb exist this shouldn't happen");
|
||||||
return(-EBUSY);
|
return(-EBUSY);
|
||||||
}
|
}
|
||||||
|
if (skb->len <= 0)
|
||||||
|
return(-EINVAL);
|
||||||
bch->inst.lock(bch->inst.privat, 0);
|
bch->inst.lock(bch->inst.privat, 0);
|
||||||
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
|
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
|
||||||
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
|
@ -1627,9 +1592,7 @@ isar_down(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||||
}
|
}
|
||||||
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
|
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
|
||||||
(hh->prim == (DL_ESTABLISH | REQUEST))) {
|
(hh->prim == (DL_ESTABLISH | REQUEST))) {
|
||||||
if (test_and_set_bit(BC_FLG_ACTIV, &bch->Flag))
|
if (!test_and_set_bit(BC_FLG_ACTIV, &bch->Flag)) {
|
||||||
ret = 0;
|
|
||||||
else {
|
|
||||||
u_int bp = bch->inst.pid.protocol[1];
|
u_int bp = bch->inst.pid.protocol[1];
|
||||||
|
|
||||||
if (bch->inst.pid.global == 1)
|
if (bch->inst.pid.global == 1)
|
||||||
|
@ -1657,8 +1620,7 @@ isar_down(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||||
bch->inst.unlock(bch->inst.privat);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
if (hh->prim != (PH_CONTROL | REQUEST))
|
if (hh->prim != (PH_CONTROL | REQUEST))
|
||||||
if (!mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, 0, skb))
|
ret = mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, 0, skb);
|
||||||
return(0);
|
|
||||||
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
||||||
int *val;
|
int *val;
|
||||||
int len;
|
int len;
|
||||||
|
@ -1704,6 +1666,7 @@ isar_down(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||||
int_errtxt("wrong modulation");
|
int_errtxt("wrong modulation");
|
||||||
/* wrong modulation or not activ */
|
/* wrong modulation or not activ */
|
||||||
// TODO
|
// TODO
|
||||||
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
} else if (hh->dinfo == HW_MOD_LASTDATA) {
|
} else if (hh->dinfo == HW_MOD_LASTDATA) {
|
||||||
test_and_set_bit(BC_FLG_DLEETX, &bch->Flag);
|
test_and_set_bit(BC_FLG_DLEETX, &bch->Flag);
|
||||||
|
|
|
@ -149,24 +149,13 @@ W6692_new_ph(dchannel_t *dch)
|
||||||
{
|
{
|
||||||
u_int prim = PH_SIGNAL | INDICATION;
|
u_int prim = PH_SIGNAL | INDICATION;
|
||||||
u_int para = 0;
|
u_int para = 0;
|
||||||
mISDNif_t *upif = &dch->inst.up;
|
|
||||||
|
|
||||||
if (dch->debug)
|
|
||||||
printk(KERN_DEBUG "%s: event %lx\n", __FUNCTION__, dch->event);
|
|
||||||
if (!test_and_clear_bit(D_L1STATECHANGE, &dch->event))
|
|
||||||
return;
|
|
||||||
switch (dch->ph_state) {
|
switch (dch->ph_state) {
|
||||||
case W_L1CMD_RST:
|
case W_L1CMD_RST:
|
||||||
dch->inst.lock(dch->inst.data, 0);
|
dch->inst.lock(dch->inst.privat, 0);
|
||||||
ph_command(dch->hw, W_L1CMD_DRC);
|
ph_command(dch->hw, W_L1CMD_DRC);
|
||||||
dch->inst.unlock(dch->inst.data);
|
dch->inst.unlock(dch->inst.privat);
|
||||||
prim = PH_CONTROL | INDICATION;
|
mISDN_queue_data(&dch->inst, FLG_MSG_UP, PH_CONTROL | INDICATION, HW_RESET, 0, NULL, 0);
|
||||||
para = HW_RESET;
|
|
||||||
while(upif) {
|
|
||||||
if_link(upif, prim, para, 0, NULL, 0);
|
|
||||||
upif = upif->clone;
|
|
||||||
}
|
|
||||||
upif = &dch->inst.up;
|
|
||||||
/* fall trough */
|
/* fall trough */
|
||||||
case W_L1IND_CD:
|
case W_L1IND_CD:
|
||||||
prim = PH_CONTROL | CONFIRM;
|
prim = PH_CONTROL | CONFIRM;
|
||||||
|
@ -195,10 +184,7 @@ W6692_new_ph(dchannel_t *dch)
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while(upif) {
|
mISDN_queue_data(&dch->inst, FLG_MSG_UP, prim, para, 0, NULL, 0);
|
||||||
if_link(upif, prim, para, 0, NULL, 0);
|
|
||||||
upif = upif->clone;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -281,8 +267,10 @@ d_retransmit(w6692pci *card)
|
||||||
|
|
||||||
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
|
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
|
||||||
del_timer(&dch->dbusytimer);
|
del_timer(&dch->dbusytimer);
|
||||||
|
#ifdef FIXME
|
||||||
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
||||||
dchannel_sched_event(dch, D_CLEARBUSY);
|
dchannel_sched_event(dch, D_CLEARBUSY);
|
||||||
|
#endif
|
||||||
if (test_bit(FLG_TX_BUSY, &dch->DFlags)) {
|
if (test_bit(FLG_TX_BUSY, &dch->DFlags)) {
|
||||||
/* Restart frame */
|
/* Restart frame */
|
||||||
dch->tx_idx = 0;
|
dch->tx_idx = 0;
|
||||||
|
@ -290,17 +278,22 @@ d_retransmit(w6692pci *card)
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "mISDN: w6692 XDU no TX_BUSY\n");
|
printk(KERN_WARNING "mISDN: w6692 XDU no TX_BUSY\n");
|
||||||
mISDN_debugprint(&dch->inst, "XDU no TX_BUSY");
|
mISDN_debugprint(&dch->inst, "XDU no TX_BUSY");
|
||||||
if (test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
if (test_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||||
if (dch->next_skb) {
|
struct sk_buff *skb = dch->next_skb;
|
||||||
dch->tx_len = dch->next_skb->len;
|
if (skb) {
|
||||||
memcpy(dch->tx_buf,
|
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||||
dch->next_skb->data,
|
dch->next_skb = NULL;
|
||||||
dch->tx_len);
|
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
|
dch->tx_len = skb->len;
|
||||||
|
memcpy(dch->tx_buf, skb->data, dch->tx_len);
|
||||||
dch->tx_idx = 0;
|
dch->tx_idx = 0;
|
||||||
W6692_fill_Dfifo(card);
|
W6692_fill_Dfifo(card);
|
||||||
dchannel_sched_event(dch, D_XMTBUFREADY);
|
skb_trim(skb, 0);
|
||||||
|
if (mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_CNF, hh->dinfo, skb))
|
||||||
|
dev_kfree_skb(skb);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "w6692 xdu irq TX_NEXT without skb\n");
|
printk(KERN_WARNING "w6692 xdu irq TX_NEXT without skb\n");
|
||||||
|
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,12 +335,11 @@ handle_rxD(w6692pci *card) {
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
count = W_D_FIFO_THRESH;
|
count = W_D_FIFO_THRESH;
|
||||||
W6692_empty_Dfifo(card, count);
|
W6692_empty_Dfifo(card, count);
|
||||||
if (card->dch.rx_skb) {
|
if (card->dch.rx_skb)
|
||||||
skb_queue_tail(&card->dch.rqueue, card->dch.rx_skb);
|
mISDN_queueup_newhead(&card->dch.inst, 0, PH_DATA_IND,
|
||||||
}
|
MISDN_ID_ANY, card->dch.rx_skb);
|
||||||
}
|
}
|
||||||
card->dch.rx_skb = NULL;
|
card->dch.rx_skb = NULL;
|
||||||
dchannel_sched_event(&card->dch, D_RCVBUFREADY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -356,21 +348,29 @@ handle_txD(w6692pci *card) {
|
||||||
|
|
||||||
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
|
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
|
||||||
del_timer(&dch->dbusytimer);
|
del_timer(&dch->dbusytimer);
|
||||||
|
#ifdef FIXME
|
||||||
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
||||||
dchannel_sched_event(dch, D_CLEARBUSY);
|
dchannel_sched_event(dch, D_CLEARBUSY);
|
||||||
|
#endif
|
||||||
if (dch->tx_idx < dch->tx_len) {
|
if (dch->tx_idx < dch->tx_len) {
|
||||||
W6692_fill_Dfifo(card);
|
W6692_fill_Dfifo(card);
|
||||||
} else {
|
} else {
|
||||||
if (test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
if (test_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||||
if (dch->next_skb) {
|
struct sk_buff *skb = dch->next_skb;
|
||||||
dch->tx_len = dch->next_skb->len;
|
if (skb) {
|
||||||
memcpy(dch->tx_buf,
|
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||||
dch->next_skb->data, dch->tx_len);
|
dch->next_skb = NULL;
|
||||||
|
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
|
dch->tx_len = skb->len;
|
||||||
|
memcpy(dch->tx_buf, skb->data, dch->tx_len);
|
||||||
dch->tx_idx = 0;
|
dch->tx_idx = 0;
|
||||||
W6692_fill_Dfifo(card);
|
W6692_fill_Dfifo(card);
|
||||||
dchannel_sched_event(dch, D_XMTBUFREADY);
|
skb_trim(skb, 0);
|
||||||
|
if (mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_CNF, hh->dinfo, skb))
|
||||||
|
dev_kfree_skb(skb);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "w6692 txD irq TX_NEXT without skb\n");
|
printk(KERN_WARNING "w6692 txD irq TX_NEXT without skb\n");
|
||||||
|
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -431,7 +431,7 @@ handle_statusD(w6692pci *card) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dchannel_sched_event(dch, D_L1STATECHANGE);
|
W6692_new_ph(dch);
|
||||||
}
|
}
|
||||||
if (cir & W_CIR_SCC) {
|
if (cir & W_CIR_SCC) {
|
||||||
v1 = ReadW6692(card, W_SQR);
|
v1 = ReadW6692(card, W_SQR);
|
||||||
|
@ -453,7 +453,7 @@ static void
|
||||||
W6692_empty_Bfifo(bchannel_t *bch, int count)
|
W6692_empty_Bfifo(bchannel_t *bch, int count)
|
||||||
{
|
{
|
||||||
u_char *ptr;
|
u_char *ptr;
|
||||||
w6692pci *card = bch->inst.data;
|
w6692pci *card = bch->inst.privat;
|
||||||
|
|
||||||
if ((bch->debug & L1_DEB_HSCX) && !(bch->debug & L1_DEB_HSCX_FIFO))
|
if ((bch->debug & L1_DEB_HSCX) && !(bch->debug & L1_DEB_HSCX_FIFO))
|
||||||
mISDN_debugprint(&bch->inst, "empty_Bfifo %d", count);
|
mISDN_debugprint(&bch->inst, "empty_Bfifo %d", count);
|
||||||
|
@ -488,7 +488,7 @@ W6692_empty_Bfifo(bchannel_t *bch, int count)
|
||||||
static void
|
static void
|
||||||
W6692_fill_Bfifo(bchannel_t *bch)
|
W6692_fill_Bfifo(bchannel_t *bch)
|
||||||
{
|
{
|
||||||
w6692pci *card = bch->inst.data;
|
w6692pci *card = bch->inst.privat;
|
||||||
int count;
|
int count;
|
||||||
u_char *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS;
|
u_char *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS;
|
||||||
|
|
||||||
|
@ -523,7 +523,7 @@ W6692_fill_Bfifo(bchannel_t *bch)
|
||||||
static int
|
static int
|
||||||
setvolume(bchannel_t *bch, int mic, struct sk_buff *skb)
|
setvolume(bchannel_t *bch, int mic, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
w6692pci *card = bch->inst.data;
|
w6692pci *card = bch->inst.privat;
|
||||||
u16 *vol = (u16 *)skb->data;
|
u16 *vol = (u16 *)skb->data;
|
||||||
u_char val;
|
u_char val;
|
||||||
|
|
||||||
|
@ -550,7 +550,7 @@ static int
|
||||||
enable_pots(bchannel_t *bch)
|
enable_pots(bchannel_t *bch)
|
||||||
{
|
{
|
||||||
w6692_bc *bhw = bch->hw;
|
w6692_bc *bhw = bch->hw;
|
||||||
w6692pci *card = bch->inst.data;
|
w6692pci *card = bch->inst.privat;
|
||||||
|
|
||||||
if ((card->pots == 0) || (bch->protocol != ISDN_PID_L1_B_64TRANS))
|
if ((card->pots == 0) || (bch->protocol != ISDN_PID_L1_B_64TRANS))
|
||||||
return(-ENODEV);
|
return(-ENODEV);
|
||||||
|
@ -567,7 +567,7 @@ static int
|
||||||
disable_pots(bchannel_t *bch)
|
disable_pots(bchannel_t *bch)
|
||||||
{
|
{
|
||||||
w6692_bc *bhw = bch->hw;
|
w6692_bc *bhw = bch->hw;
|
||||||
w6692pci *card = bch->inst.data;
|
w6692pci *card = bch->inst.privat;
|
||||||
|
|
||||||
if (card->pots == 0)
|
if (card->pots == 0)
|
||||||
return(-ENODEV);
|
return(-ENODEV);
|
||||||
|
@ -580,7 +580,7 @@ disable_pots(bchannel_t *bch)
|
||||||
static int
|
static int
|
||||||
mode_w6692(bchannel_t *bch, int bc, int protocol)
|
mode_w6692(bchannel_t *bch, int bc, int protocol)
|
||||||
{
|
{
|
||||||
w6692pci *card = bch->inst.data;
|
w6692pci *card = bch->inst.privat;
|
||||||
w6692_bc *bhw = bch->hw;
|
w6692_bc *bhw = bch->hw;
|
||||||
|
|
||||||
|
|
||||||
|
@ -605,7 +605,6 @@ mode_w6692(bchannel_t *bch, int bc, int protocol)
|
||||||
dev_kfree_skb(bch->next_skb);
|
dev_kfree_skb(bch->next_skb);
|
||||||
bch->next_skb = NULL;
|
bch->next_skb = NULL;
|
||||||
}
|
}
|
||||||
discard_queue(&bch->rqueue);
|
|
||||||
WriteW6692B(card, bch->channel, W_B_MODE, bhw->b_mode);
|
WriteW6692B(card, bch->channel, W_B_MODE, bhw->b_mode);
|
||||||
WriteW6692B(card, bch->channel, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
|
WriteW6692B(card, bch->channel, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
|
||||||
break;
|
break;
|
||||||
|
@ -615,7 +614,6 @@ mode_w6692(bchannel_t *bch, int bc, int protocol)
|
||||||
WriteW6692B(card, bch->channel, W_B_MODE, bhw->b_mode);
|
WriteW6692B(card, bch->channel, W_B_MODE, bhw->b_mode);
|
||||||
WriteW6692B(card, bch->channel, W_B_EXIM, 0);
|
WriteW6692B(card, bch->channel, W_B_EXIM, 0);
|
||||||
WriteW6692B(card, bch->channel, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT | W_B_CMDR_XRST);
|
WriteW6692B(card, bch->channel, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT | W_B_CMDR_XRST);
|
||||||
bch_sched_event(bch, B_XMTBUFREADY);
|
|
||||||
break;
|
break;
|
||||||
case (ISDN_PID_L1_B_64HDLC):
|
case (ISDN_PID_L1_B_64HDLC):
|
||||||
bch->protocol = protocol;
|
bch->protocol = protocol;
|
||||||
|
@ -625,7 +623,6 @@ mode_w6692(bchannel_t *bch, int bc, int protocol)
|
||||||
WriteW6692B(card, bch->channel, W_B_ADM2, 0xff);
|
WriteW6692B(card, bch->channel, W_B_ADM2, 0xff);
|
||||||
WriteW6692B(card, bch->channel, W_B_EXIM, 0);
|
WriteW6692B(card, bch->channel, W_B_EXIM, 0);
|
||||||
WriteW6692B(card, bch->channel, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT | W_B_CMDR_XRST);
|
WriteW6692B(card, bch->channel, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT | W_B_CMDR_XRST);
|
||||||
bch_sched_event(bch, B_XMTBUFREADY);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mISDN_debugprint(&bch->inst, "prot not known %x", protocol);
|
mISDN_debugprint(&bch->inst, "prot not known %x", protocol);
|
||||||
|
@ -643,13 +640,21 @@ send_next(bchannel_t *bch)
|
||||||
W6692_fill_Bfifo(bch);
|
W6692_fill_Bfifo(bch);
|
||||||
else {
|
else {
|
||||||
bch->tx_idx = 0;
|
bch->tx_idx = 0;
|
||||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
if (test_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||||
if (bch->next_skb) {
|
struct sk_buff *skb = bch->next_skb;
|
||||||
bch->tx_len = bch->next_skb->len;
|
if (skb) {
|
||||||
memcpy(bch->tx_buf, bch->next_skb->data, bch->tx_len);
|
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||||
|
|
||||||
|
bch->next_skb = NULL;
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
|
bch->tx_len = skb->len;
|
||||||
|
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||||
W6692_fill_Bfifo(bch);
|
W6692_fill_Bfifo(bch);
|
||||||
|
skb_trim(skb, 0);
|
||||||
|
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||||
} else {
|
} else {
|
||||||
bch->tx_len = 0;
|
bch->tx_len = 0;
|
||||||
|
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
printk(KERN_WARNING "W6692 tx irq TX_NEXT without skb\n");
|
printk(KERN_WARNING "W6692 tx irq TX_NEXT without skb\n");
|
||||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||||
}
|
}
|
||||||
|
@ -657,7 +662,6 @@ send_next(bchannel_t *bch)
|
||||||
bch->tx_len = 0;
|
bch->tx_len = 0;
|
||||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||||
}
|
}
|
||||||
bch_sched_event(bch, B_XMTBUFREADY);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -711,9 +715,8 @@ W6692B_interrupt(w6692pci *card, int ch)
|
||||||
printk(KERN_WARNING "Bchan receive out of memory\n");
|
printk(KERN_WARNING "Bchan receive out of memory\n");
|
||||||
else {
|
else {
|
||||||
memcpy(skb_put(skb, bch->rx_idx), bch->rx_buf, bch->rx_idx);
|
memcpy(skb_put(skb, bch->rx_idx), bch->rx_buf, bch->rx_idx);
|
||||||
skb_queue_tail(&bch->rqueue, skb);
|
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||||
}
|
}
|
||||||
bch_sched_event(bch, B_RCVBUFREADY);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bch->rx_idx = 0;
|
bch->rx_idx = 0;
|
||||||
|
@ -739,9 +742,8 @@ W6692B_interrupt(w6692pci *card, int ch)
|
||||||
printk(KERN_WARNING "Bchan receive out of memory\n");
|
printk(KERN_WARNING "Bchan receive out of memory\n");
|
||||||
else {
|
else {
|
||||||
memcpy(skb_put(skb, bch->rx_idx), bch->rx_buf, bch->rx_idx);
|
memcpy(skb_put(skb, bch->rx_idx), bch->rx_buf, bch->rx_idx);
|
||||||
skb_queue_tail(&bch->rqueue, skb);
|
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||||
}
|
}
|
||||||
bch_sched_event(bch, B_RCVBUFREADY);
|
|
||||||
bch->rx_idx = 0;
|
bch->rx_idx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -887,7 +889,7 @@ dbusy_timer_handler(dchannel_t *dch)
|
||||||
int rbch, star;
|
int rbch, star;
|
||||||
|
|
||||||
if (test_bit(FLG_DBUSY_TIMER, &dch->DFlags)) {
|
if (test_bit(FLG_DBUSY_TIMER, &dch->DFlags)) {
|
||||||
if (dch->inst.lock(dch->inst.data, 1)) {
|
if (dch->inst.lock(dch->inst.privat, 1)) {
|
||||||
dch->dbusytimer.expires = jiffies + 1;
|
dch->dbusytimer.expires = jiffies + 1;
|
||||||
add_timer(&dch->dbusytimer);
|
add_timer(&dch->dbusytimer);
|
||||||
return;
|
return;
|
||||||
|
@ -911,7 +913,7 @@ dbusy_timer_handler(dchannel_t *dch)
|
||||||
/* Transmitter reset */
|
/* Transmitter reset */
|
||||||
WriteW6692(card, W_D_CMDR, W_D_CMDR_XRST); /* Transmitter reset */
|
WriteW6692(card, W_D_CMDR, W_D_CMDR_XRST); /* Transmitter reset */
|
||||||
}
|
}
|
||||||
dch->inst.unlock(dch->inst.data);
|
dch->inst.unlock(dch->inst.privat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1036,16 +1038,12 @@ MODULE_PARM(layermask, MODULE_PARM_T);
|
||||||
/* Layer2 -> Layer 1 Transfer */
|
/* Layer2 -> Layer 1 Transfer */
|
||||||
/******************************/
|
/******************************/
|
||||||
static int
|
static int
|
||||||
w6692_l2l1B(mISDNif_t *hif, struct sk_buff *skb)
|
w6692_l2l1B(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
bchannel_t *bch;
|
bchannel_t *bch = container_of(inst, bchannel_t, inst);
|
||||||
int ret = -EINVAL;
|
int ret = 0;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||||
|
|
||||||
if (!hif || !skb)
|
|
||||||
return(ret);
|
|
||||||
hh = mISDN_HEAD_P(skb);
|
|
||||||
bch = hif->fdata;
|
|
||||||
if ((hh->prim == PH_DATA_REQ) ||
|
if ((hh->prim == PH_DATA_REQ) ||
|
||||||
(hh->prim == (DL_DATA | REQUEST))) {
|
(hh->prim == (DL_DATA | REQUEST))) {
|
||||||
if (bch->next_skb) {
|
if (bch->next_skb) {
|
||||||
|
@ -1053,46 +1051,50 @@ w6692_l2l1B(mISDNif_t *hif, struct sk_buff *skb)
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
return(-EBUSY);
|
return(-EBUSY);
|
||||||
}
|
}
|
||||||
bch->inst.lock(bch->inst.data, 0);
|
if (skb->len <= 0)
|
||||||
|
return(-EINVAL);
|
||||||
|
bch->inst.lock(bch->inst.privat, 0);
|
||||||
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
|
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
|
||||||
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||||
bch->next_skb = skb;
|
bch->next_skb = skb;
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
return(0);
|
return(0);
|
||||||
} else {
|
} else {
|
||||||
bch->tx_len = skb->len;
|
bch->tx_len = skb->len;
|
||||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||||
bch->tx_idx = 0;
|
bch->tx_idx = 0;
|
||||||
W6692_fill_Bfifo(bch);
|
W6692_fill_Bfifo(bch);
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
|
#ifdef FIXME
|
||||||
if ((bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
if ((bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
||||||
&& bch->dev)
|
&& bch->dev)
|
||||||
hif = &bch->dev->rport.pif;
|
hif = &bch->dev->rport.pif;
|
||||||
else
|
else
|
||||||
hif = &bch->inst.up;
|
hif = &bch->inst.up;
|
||||||
|
#endif
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
return(if_newhead(hif, hh->prim | CONFIRM,
|
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM,
|
||||||
hh->dinfo, skb));
|
hh->dinfo, skb));
|
||||||
}
|
}
|
||||||
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
|
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
|
||||||
(hh->prim == (DL_ESTABLISH | REQUEST))) {
|
(hh->prim == (DL_ESTABLISH | REQUEST))) {
|
||||||
if (test_and_set_bit(BC_FLG_ACTIV, &bch->Flag))
|
if (!test_and_set_bit(BC_FLG_ACTIV, &bch->Flag)) {
|
||||||
ret = 0;
|
bch->inst.lock(bch->inst.privat, 0);
|
||||||
else {
|
|
||||||
bch->inst.lock(bch->inst.data, 0);
|
|
||||||
ret = mode_w6692(bch, bch->channel, bch->inst.pid.protocol[1]);
|
ret = mode_w6692(bch, bch->channel, bch->inst.pid.protocol[1]);
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
}
|
}
|
||||||
|
#ifdef FIXME
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
||||||
if (bch->dev)
|
if (bch->dev)
|
||||||
if_link(&bch->dev->rport.pif,
|
if_link(&bch->dev->rport.pif,
|
||||||
hh->prim | CONFIRM, 0, 0, NULL, 0);
|
hh->prim | CONFIRM, 0, 0, NULL, 0);
|
||||||
|
#endif
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
return(if_newhead(&bch->inst.up, hh->prim | CONFIRM, ret, skb));
|
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, ret, skb));
|
||||||
} else if ((hh->prim == (PH_DEACTIVATE | REQUEST)) ||
|
} else if ((hh->prim == (PH_DEACTIVATE | REQUEST)) ||
|
||||||
(hh->prim == (DL_RELEASE | REQUEST)) ||
|
(hh->prim == (DL_RELEASE | REQUEST)) ||
|
||||||
(hh->prim == (MGR_DISCONNECT | REQUEST))) {
|
((hh->prim == (PH_CONTROL | REQUEST) && (hh->dinfo == HW_DEACTIVATE)))) {
|
||||||
bch->inst.lock(bch->inst.data, 0);
|
bch->inst.lock(bch->inst.privat, 0);
|
||||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||||
dev_kfree_skb(bch->next_skb);
|
dev_kfree_skb(bch->next_skb);
|
||||||
bch->next_skb = NULL;
|
bch->next_skb = NULL;
|
||||||
|
@ -1100,20 +1102,20 @@ w6692_l2l1B(mISDNif_t *hif, struct sk_buff *skb)
|
||||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||||
mode_w6692(bch, bch->channel, ISDN_PID_NONE);
|
mode_w6692(bch, bch->channel, ISDN_PID_NONE);
|
||||||
test_and_clear_bit(BC_FLG_ACTIV, &bch->Flag);
|
test_and_clear_bit(BC_FLG_ACTIV, &bch->Flag);
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
skb_trim(skb, 0);
|
skb_trim(skb, 0);
|
||||||
if (hh->prim != (MGR_DISCONNECT | REQUEST)) {
|
if (hh->prim != (PH_CONTROL | REQUEST)) {
|
||||||
|
#ifdef FIXME
|
||||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
||||||
if (bch->dev)
|
if (bch->dev)
|
||||||
if_link(&bch->dev->rport.pif,
|
if_link(&bch->dev->rport.pif,
|
||||||
hh->prim | CONFIRM, 0, 0, NULL, 0);
|
hh->prim | CONFIRM, 0, 0, NULL, 0);
|
||||||
if (!if_newhead(&bch->inst.up, hh->prim | CONFIRM, 0, skb))
|
#endif
|
||||||
|
if (!mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, 0, skb))
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
ret = 0;
|
|
||||||
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
||||||
ret = 0;
|
bch->inst.lock(bch->inst.privat, 0);
|
||||||
bch->inst.lock(bch->inst.data, 0);
|
|
||||||
if (hh->dinfo == HW_POTS_ON) {
|
if (hh->dinfo == HW_POTS_ON) {
|
||||||
ret = enable_pots(bch);
|
ret = enable_pots(bch);
|
||||||
} else if (hh->dinfo == HW_POTS_OFF) {
|
} else if (hh->dinfo == HW_POTS_OFF) {
|
||||||
|
@ -1124,10 +1126,11 @@ w6692_l2l1B(mISDNif_t *hif, struct sk_buff *skb)
|
||||||
ret = setvolume(bch, 0, skb);
|
ret = setvolume(bch, 0, skb);
|
||||||
} else
|
} else
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
bch->inst.unlock(bch->inst.data);
|
bch->inst.unlock(bch->inst.privat);
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_WARNING "%s: unknown prim(%x)\n",
|
printk(KERN_WARNING "%s: unknown prim(%x)\n",
|
||||||
__FUNCTION__, hh->prim);
|
__FUNCTION__, hh->prim);
|
||||||
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
if (!ret)
|
if (!ret)
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
|
@ -1135,48 +1138,43 @@ w6692_l2l1B(mISDNif_t *hif, struct sk_buff *skb)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
w6692_l1hwD(mISDNif_t *hif, struct sk_buff *skb)
|
w6692_l1hwD(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
dchannel_t *dch;
|
dchannel_t *dch = container_of(inst, dchannel_t, inst);
|
||||||
int ret = -EINVAL;
|
int ret = 0;
|
||||||
mISDN_head_t *hh;
|
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||||
|
|
||||||
if (!hif || !skb)
|
|
||||||
return(ret);
|
|
||||||
hh = mISDN_HEAD_P(skb);
|
|
||||||
dch = hif->fdata;
|
|
||||||
ret = 0;
|
|
||||||
if (hh->prim == PH_DATA_REQ) {
|
if (hh->prim == PH_DATA_REQ) {
|
||||||
if (dch->next_skb) {
|
if (dch->next_skb) {
|
||||||
mISDN_debugprint(&dch->inst, "w6692 l2l1 next_skb exist this shouldn't happen");
|
mISDN_debugprint(&dch->inst, "w6692 l2l1 next_skb exist this shouldn't happen");
|
||||||
return(-EBUSY);
|
return(-EBUSY);
|
||||||
}
|
}
|
||||||
dch->inst.lock(dch->inst.data,0);
|
dch->inst.lock(dch->inst.privat,0);
|
||||||
if (test_and_set_bit(FLG_TX_BUSY, &dch->DFlags)) {
|
if (test_and_set_bit(FLG_TX_BUSY, &dch->DFlags)) {
|
||||||
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
|
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||||
dch->next_skb = skb;
|
dch->next_skb = skb;
|
||||||
dch->inst.unlock(dch->inst.data);
|
dch->inst.unlock(dch->inst.privat);
|
||||||
return(0);
|
return(0);
|
||||||
} else {
|
} else {
|
||||||
dch->tx_len = skb->len;
|
dch->tx_len = skb->len;
|
||||||
memcpy(dch->tx_buf, skb->data, dch->tx_len);
|
memcpy(dch->tx_buf, skb->data, dch->tx_len);
|
||||||
dch->tx_idx = 0;
|
dch->tx_idx = 0;
|
||||||
W6692_fill_Dfifo(dch->hw);
|
W6692_fill_Dfifo(dch->hw);
|
||||||
dch->inst.unlock(dch->inst.data);
|
dch->inst.unlock(dch->inst.privat);
|
||||||
return(if_newhead(&dch->inst.up, PH_DATA_CNF,
|
return(mISDN_queueup_newhead(inst, 0, PH_DATA_CNF,
|
||||||
hh->dinfo, skb));
|
hh->dinfo, skb));
|
||||||
}
|
}
|
||||||
} else if (hh->prim == (PH_SIGNAL | REQUEST)) {
|
} else if (hh->prim == (PH_SIGNAL | REQUEST)) {
|
||||||
dch->inst.lock(dch->inst.data,0);
|
dch->inst.lock(dch->inst.privat,0);
|
||||||
if (hh->dinfo == INFO3_P8)
|
if (hh->dinfo == INFO3_P8)
|
||||||
ph_command(dch->hw, W_L1CMD_AR8);
|
ph_command(dch->hw, W_L1CMD_AR8);
|
||||||
else if (hh->dinfo == INFO3_P10)
|
else if (hh->dinfo == INFO3_P10)
|
||||||
ph_command(dch->hw, W_L1CMD_AR10);
|
ph_command(dch->hw, W_L1CMD_AR10);
|
||||||
else
|
else
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
dch->inst.unlock(dch->inst.data);
|
dch->inst.unlock(dch->inst.privat);
|
||||||
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
||||||
dch->inst.lock(dch->inst.data,0);
|
dch->inst.lock(dch->inst.privat,0);
|
||||||
if (hh->dinfo == HW_RESET) {
|
if (hh->dinfo == HW_RESET) {
|
||||||
if (dch->ph_state != W_L1IND_DRD)
|
if (dch->ph_state != W_L1IND_DRD)
|
||||||
ph_command(dch->hw, W_L1CMD_RST);
|
ph_command(dch->hw, W_L1CMD_RST);
|
||||||
|
@ -1184,7 +1182,6 @@ w6692_l1hwD(mISDNif_t *hif, struct sk_buff *skb)
|
||||||
} else if (hh->dinfo == HW_POWERUP) {
|
} else if (hh->dinfo == HW_POWERUP) {
|
||||||
ph_command(dch->hw, W_L1CMD_ECK);
|
ph_command(dch->hw, W_L1CMD_ECK);
|
||||||
} else if (hh->dinfo == HW_DEACTIVATE) {
|
} else if (hh->dinfo == HW_DEACTIVATE) {
|
||||||
discard_queue(&dch->rqueue);
|
|
||||||
if (dch->next_skb) {
|
if (dch->next_skb) {
|
||||||
dev_kfree_skb(dch->next_skb);
|
dev_kfree_skb(dch->next_skb);
|
||||||
dch->next_skb = NULL;
|
dch->next_skb = NULL;
|
||||||
|
@ -1193,8 +1190,10 @@ w6692_l1hwD(mISDNif_t *hif, struct sk_buff *skb)
|
||||||
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
||||||
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
|
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
|
||||||
del_timer(&dch->dbusytimer);
|
del_timer(&dch->dbusytimer);
|
||||||
|
#ifdef FIXME
|
||||||
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
||||||
dchannel_sched_event(dch, D_CLEARBUSY);
|
dchannel_sched_event(dch, D_CLEARBUSY);
|
||||||
|
#endif
|
||||||
} else if ((hh->dinfo & HW_TESTLOOP) == HW_TESTLOOP) {
|
} else if ((hh->dinfo & HW_TESTLOOP) == HW_TESTLOOP) {
|
||||||
u_char val = 0;
|
u_char val = 0;
|
||||||
|
|
||||||
|
@ -1209,7 +1208,7 @@ w6692_l1hwD(mISDNif_t *hif, struct sk_buff *skb)
|
||||||
hh->dinfo);
|
hh->dinfo);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
dch->inst.unlock(dch->inst.data);
|
dch->inst.unlock(dch->inst.privat);
|
||||||
} else {
|
} else {
|
||||||
if (dch->debug & L1_DEB_WARN)
|
if (dch->debug & L1_DEB_WARN)
|
||||||
mISDN_debugprint(&dch->inst, "w6692_l1hw unknown prim %x",
|
mISDN_debugprint(&dch->inst, "w6692_l1hw unknown prim %x",
|
||||||
|
@ -1275,7 +1274,6 @@ release_card(w6692pci *card)
|
||||||
mISDN_free_bch(&card->bch[1]);
|
mISDN_free_bch(&card->bch[1]);
|
||||||
mISDN_free_bch(&card->bch[0]);
|
mISDN_free_bch(&card->bch[0]);
|
||||||
mISDN_free_dch(&card->dch);
|
mISDN_free_dch(&card->dch);
|
||||||
w6692.ctrl(card->dch.inst.up.peer, MGR_DISCONNECT | REQUEST, &card->dch.inst.up);
|
|
||||||
w6692.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
|
w6692.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||||
list_del(&card->list);
|
list_del(&card->list);
|
||||||
unlock_dev(card);
|
unlock_dev(card);
|
||||||
|
@ -1328,22 +1326,17 @@ w6692_manager(void *data, u_int prim, void *arg) {
|
||||||
bch_set_para(&card->bch[channel], &inst->st->para);
|
bch_set_para(&card->bch[channel], &inst->st->para);
|
||||||
break;
|
break;
|
||||||
case MGR_UNREGLAYER | REQUEST:
|
case MGR_UNREGLAYER | REQUEST:
|
||||||
if (channel == 2) {
|
|
||||||
inst->down.fdata = &card->dch;
|
|
||||||
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
||||||
HW_DEACTIVATE, 0, NULL, 0))) {
|
HW_DEACTIVATE, 0, NULL, 0))) {
|
||||||
if (w6692_l1hwD(&inst->down, skb))
|
if (channel == 2) {
|
||||||
|
if (w6692_l1hwD(inst, skb))
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
inst->down.fdata = &card->bch[channel];
|
if (w6692_l2l1B(inst, skb))
|
||||||
if ((skb = create_link_skb(MGR_DISCONNECT | REQUEST,
|
|
||||||
0, 0, NULL, 0))) {
|
|
||||||
if (w6692_l2l1B(&inst->down, skb))
|
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
w6692.ctrl(inst->up.peer, MGR_DISCONNECT | REQUEST, &inst->up);
|
printk(KERN_WARNING "no SKB in %s MGR_UNREGLAYER | REQUEST\n", __FUNCTION__);
|
||||||
w6692.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
|
w6692.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||||
break;
|
break;
|
||||||
case MGR_CLRSTPARA | INDICATION:
|
case MGR_CLRSTPARA | INDICATION:
|
||||||
|
@ -1361,33 +1354,18 @@ w6692_manager(void *data, u_int prim, void *arg) {
|
||||||
w6692.refcnt--;
|
w6692.refcnt--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MGR_CONNECT | REQUEST:
|
|
||||||
return(mISDN_ConnectIF(inst, arg));
|
|
||||||
case MGR_SETIF | REQUEST:
|
|
||||||
case MGR_SETIF | INDICATION:
|
|
||||||
if (channel==2)
|
|
||||||
return(mISDN_SetIF(inst, arg, prim, w6692_l1hwD, NULL,
|
|
||||||
&card->dch));
|
|
||||||
else
|
|
||||||
return(mISDN_SetIF(inst, arg, prim, w6692_l2l1B, NULL,
|
|
||||||
&card->bch[channel]));
|
|
||||||
break;
|
|
||||||
case MGR_DISCONNECT | REQUEST:
|
|
||||||
case MGR_DISCONNECT | INDICATION:
|
|
||||||
return(mISDN_DisConnectIF(inst, arg));
|
|
||||||
case MGR_SETSTACK | INDICATION:
|
case MGR_SETSTACK | INDICATION:
|
||||||
if ((channel!=2) && (inst->pid.global == 2)) {
|
if ((channel!=2) && (inst->pid.global == 2)) {
|
||||||
inst->down.fdata = &card->bch[channel];
|
|
||||||
if ((skb = create_link_skb(PH_ACTIVATE | REQUEST,
|
if ((skb = create_link_skb(PH_ACTIVATE | REQUEST,
|
||||||
0, 0, NULL, 0))) {
|
0, 0, NULL, 0))) {
|
||||||
if (w6692_l2l1B(&inst->down, skb))
|
if (w6692_l2l1B(inst, skb))
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
}
|
}
|
||||||
if (inst->pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
if (inst->pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
||||||
if_link(&inst->up, DL_ESTABLISH | INDICATION,
|
mISDN_queue_data(inst, FLG_MSG_UP, DL_ESTABLISH | INDICATION,
|
||||||
0, 0, NULL, 0);
|
0, 0, NULL, 0);
|
||||||
else
|
else
|
||||||
if_link(&inst->up, PH_ACTIVATE | INDICATION,
|
mISDN_queue_data(inst, FLG_MSG_UP, PH_ACTIVATE | INDICATION,
|
||||||
0, 0, NULL, 0);
|
0, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1425,14 +1403,14 @@ static int __devinit setup_instance(w6692pci *card)
|
||||||
card->dch.inst.unlock = unlock_dev;
|
card->dch.inst.unlock = unlock_dev;
|
||||||
card->dch.inst.pid.layermask = ISDN_LAYER(0);
|
card->dch.inst.pid.layermask = ISDN_LAYER(0);
|
||||||
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_TE_S0;
|
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_TE_S0;
|
||||||
mISDN_init_instance(&card->dch.inst, &w6692, card);
|
mISDN_init_instance(&card->dch.inst, &w6692, card, w6692_l1hwD);
|
||||||
sprintf(card->dch.inst.name, "W6692_%d", w6692_cnt+1);
|
sprintf(card->dch.inst.name, "W6692_%d", w6692_cnt+1);
|
||||||
mISDN_set_dchannel_pid(&pid, protocol[w6692_cnt], layermask[w6692_cnt]);
|
mISDN_set_dchannel_pid(&pid, protocol[w6692_cnt], layermask[w6692_cnt]);
|
||||||
mISDN_init_dch(&card->dch);
|
mISDN_init_dch(&card->dch);
|
||||||
card->dch.hw = card;
|
card->dch.hw = card;
|
||||||
for (i=0; i<2; i++) {
|
for (i=0; i<2; i++) {
|
||||||
card->bch[i].channel = i;
|
card->bch[i].channel = i;
|
||||||
mISDN_init_instance(&card->bch[i].inst, &w6692, card);
|
mISDN_init_instance(&card->bch[i].inst, &w6692, card, w6692_l2l1B);
|
||||||
card->bch[i].inst.pid.layermask = ISDN_LAYER(0);
|
card->bch[i].inst.pid.layermask = ISDN_LAYER(0);
|
||||||
card->bch[i].inst.lock = lock_dev;
|
card->bch[i].inst.lock = lock_dev;
|
||||||
card->bch[i].inst.unlock = unlock_dev;
|
card->bch[i].inst.unlock = unlock_dev;
|
||||||
|
|
Loading…
Reference in New Issue