- 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 "isac.h"
|
||||
#include "layer1.h"
|
||||
#include "helper.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define SPIN_DEBUG
|
||||
|
@ -282,7 +281,7 @@ __write_ctrl_pciv2(fritzpnppci *fc, hdlc_hw_t *hdlc, int channel) {
|
|||
|
||||
void
|
||||
write_ctrl(bchannel_t *bch, int which) {
|
||||
fritzpnppci *fc = bch->inst.data;
|
||||
fritzpnppci *fc = bch->inst.privat;
|
||||
hdlc_hw_t *hdlc = bch->hw;
|
||||
|
||||
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;
|
||||
write_ctrl(bch, 1);
|
||||
hdlc->ctrl.sr.cmd = 0;
|
||||
bch_sched_event(bch, B_XMTBUFREADY);
|
||||
// FIXME bch_sched_event(bch, B_XMTBUFREADY);
|
||||
break;
|
||||
case (ISDN_PID_L1_B_64HDLC):
|
||||
bch->protocol = protocol;
|
||||
|
@ -384,7 +383,7 @@ modehdlc(bchannel_t *bch, int bc, int protocol)
|
|||
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
|
||||
write_ctrl(bch, 1);
|
||||
hdlc->ctrl.sr.cmd = 0;
|
||||
bch_sched_event(bch, B_XMTBUFREADY);
|
||||
// FIXME bch_sched_event(bch, B_XMTBUFREADY);
|
||||
break;
|
||||
default:
|
||||
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 idx = bch->channel ? AVM_HDLC_2 : AVM_HDLC_1;
|
||||
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))
|
||||
mISDN_debugprint(&bch->inst, "hdlc_empty_fifo %d", count);
|
||||
|
@ -463,7 +462,7 @@ hdlc_empty_fifo(bchannel_t *bch, int count)
|
|||
static void
|
||||
hdlc_fill_fifo(bchannel_t *bch)
|
||||
{
|
||||
fritzpnppci *fc = bch->inst.data;
|
||||
fritzpnppci *fc = bch->inst.privat;
|
||||
hdlc_hw_t *hdlc = bch->hw;
|
||||
int count, cnt =0;
|
||||
u_char *p;
|
||||
|
@ -542,21 +541,28 @@ HDLC_irq_xpr(bchannel_t *bch)
|
|||
hdlc_fill_fifo(bch);
|
||||
else {
|
||||
bch->tx_idx = 0;
|
||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||
if (bch->next_skb) {
|
||||
bch->tx_len = bch->next_skb->len;
|
||||
memcpy(bch->tx_buf, bch->next_skb->data, bch->tx_len);
|
||||
if (test_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||
struct sk_buff *skb = bch->next_skb;
|
||||
mISDN_head_t *hh;
|
||||
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);
|
||||
skb_trim(skb, 0);
|
||||
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||
} else {
|
||||
bch->tx_len = 0;
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
bch->tx_len = 0;
|
||||
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 {
|
||||
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->rx_idx = 0;
|
||||
bch_sched_event(bch, B_RCVBUFREADY);
|
||||
} else {
|
||||
if (bch->debug & L1_DEB_HSCX)
|
||||
mISDN_debugprint(&bch->inst, "invalid frame");
|
||||
|
@ -811,54 +816,52 @@ avm_fritzv2_interrupt(int intno, void *dev_id, struct pt_regs *regs)
|
|||
}
|
||||
|
||||
static int
|
||||
hdlc_down(mISDNif_t *hif, struct sk_buff *skb)
|
||||
hdlc_down(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||
{
|
||||
bchannel_t *bch;
|
||||
int ret = -EINVAL;
|
||||
int ret = 0;
|
||||
mISDN_head_t *hh;
|
||||
|
||||
if (!hif || !skb)
|
||||
return(ret);
|
||||
hh = mISDN_HEAD_P(skb);
|
||||
bch = hif->fdata;
|
||||
bch = container_of(inst, bchannel_t, inst);
|
||||
if ((hh->prim == PH_DATA_REQ) ||
|
||||
(hh->prim == (DL_DATA | REQUEST))) {
|
||||
if (bch->next_skb) {
|
||||
mISDN_debugprint(&bch->inst, " l2l1 next_skb exist this shouldn't happen");
|
||||
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)) {
|
||||
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||
bch->next_skb = skb;
|
||||
bch->inst.unlock(bch->inst.data);
|
||||
bch->inst.unlock(bch->inst.privat);
|
||||
return(0);
|
||||
} else {
|
||||
bch->tx_len = skb->len;
|
||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||
bch->tx_idx = 0;
|
||||
hdlc_fill_fifo(bch);
|
||||
bch->inst.unlock(bch->inst.data);
|
||||
bch->inst.unlock(bch->inst.privat);
|
||||
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));
|
||||
}
|
||||
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
|
||||
(hh->prim == (DL_ESTABLISH | REQUEST))) {
|
||||
if (test_and_set_bit(BC_FLG_ACTIV, &bch->Flag))
|
||||
ret = 0;
|
||||
else {
|
||||
bch->inst.lock(bch->inst.data,0);
|
||||
if (!test_and_set_bit(BC_FLG_ACTIV, &bch->Flag)) {
|
||||
bch->inst.lock(bch->inst.privat,0);
|
||||
ret = modehdlc(bch, bch->channel,
|
||||
bch->inst.pid.protocol[1]);
|
||||
bch->inst.unlock(bch->inst.data);
|
||||
bch->inst.unlock(bch->inst.privat);
|
||||
}
|
||||
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)) ||
|
||||
(hh->prim == (DL_RELEASE | REQUEST)) ||
|
||||
(hh->prim == (MGR_DISCONNECT | REQUEST))) {
|
||||
bch->inst.lock(bch->inst.data,0);
|
||||
((hh->prim == (PH_CONTROL | REQUEST) && (hh->dinfo == HW_DEACTIVATE)))) {
|
||||
bch->inst.lock(bch->inst.privat,0);
|
||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||
dev_kfree_skb(bch->next_skb);
|
||||
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);
|
||||
modehdlc(bch, bch->channel, 0);
|
||||
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);
|
||||
if (hh->prim != (MGR_DISCONNECT | REQUEST))
|
||||
if (!if_newhead(&bch->inst.up, hh->prim | CONFIRM, 0, skb))
|
||||
return(0);
|
||||
ret = 0;
|
||||
if (hh->prim != (PH_CONTROL | REQUEST))
|
||||
ret = mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, 0, skb);
|
||||
} else {
|
||||
printk(KERN_WARNING "hdlc_down unknown prim(%x)\n", hh->prim);
|
||||
ret = -EINVAL;
|
||||
|
@ -1108,7 +1109,6 @@ release_card(fritzpnppci *card)
|
|||
mISDN_free_bch(&card->bch[1]);
|
||||
mISDN_free_bch(&card->bch[0]);
|
||||
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);
|
||||
list_del(&card->list);
|
||||
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);
|
||||
break;
|
||||
case MGR_UNREGLAYER | REQUEST:
|
||||
if (channel == 2) {
|
||||
inst->down.fdata = &card->dch;
|
||||
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
||||
HW_DEACTIVATE, 0, NULL, 0))) {
|
||||
if (mISDN_ISAC_l1hw(&inst->down, skb))
|
||||
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
||||
HW_DEACTIVATE, 0, NULL, 0))) {
|
||||
if (channel == 2) {
|
||||
if (mISDN_ISAC_l1hw(inst, skb))
|
||||
dev_kfree_skb(skb);
|
||||
} else {
|
||||
if (hdlc_down(inst, skb))
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
} else {
|
||||
inst->down.fdata = &card->bch[channel];
|
||||
if ((skb = create_link_skb(MGR_DISCONNECT | REQUEST,
|
||||
0, 0, NULL, 0))) {
|
||||
if (hdlc_down(&inst->down, skb))
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
fritz.ctrl(inst->up.peer, MGR_DISCONNECT | REQUEST, &inst->up);
|
||||
} else
|
||||
printk(KERN_WARNING "no SKB in %s MGR_UNREGLAYER | REQUEST\n", __FUNCTION__);
|
||||
fritz.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||
break;
|
||||
case MGR_CLRSTPARA | INDICATION:
|
||||
|
@ -1199,33 +1194,18 @@ fritz_manager(void *data, u_int prim, void *arg) {
|
|||
fritz.refcnt--;
|
||||
}
|
||||
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:
|
||||
if ((channel!=2) && (inst->pid.global == 2)) {
|
||||
inst->down.fdata = &card->bch[channel];
|
||||
if ((skb = create_link_skb(PH_ACTIVATE | REQUEST,
|
||||
0, 0, NULL, 0))) {
|
||||
if (hdlc_down(&inst->down, skb))
|
||||
if (hdlc_down(inst, skb))
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
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);
|
||||
else
|
||||
if_link(&inst->up, PH_ACTIVATE | INDICATION,
|
||||
mISDN_queue_data(inst, FLG_MSG_UP, PH_ACTIVATE | INDICATION,
|
||||
0, 0, NULL, 0);
|
||||
}
|
||||
break;
|
||||
|
@ -1251,13 +1231,13 @@ static int __devinit setup_instance(fritzpnppci *card)
|
|||
card->dch.inst.unlock = unlock_dev;
|
||||
card->dch.inst.pid.layermask = ISDN_LAYER(0);
|
||||
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);
|
||||
mISDN_set_dchannel_pid(&pid, protocol[fritz_cnt], layermask[fritz_cnt]);
|
||||
mISDN_init_dch(&card->dch);
|
||||
for (i=0; i<2; 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.lock = lock_dev;
|
||||
card->bch[i].inst.unlock = unlock_dev;
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
* This file is (c) under GNU PUBLIC LICENSE
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _mISDN_BCHANNEL_H
|
||||
#define _mISDN_BCHANNEL_H
|
||||
#include <linux/mISDNif.h>
|
||||
#ifdef HAS_WORKQUEUE
|
||||
#include <linux/workqueue.h>
|
||||
|
@ -22,6 +23,7 @@
|
|||
#ifdef MISDN_MEMDEBUG
|
||||
#include "memdbg.h"
|
||||
#endif
|
||||
#include "helper.h"
|
||||
|
||||
#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
|
||||
static inline void
|
||||
bch_sched_event(bchannel_t *bch, int event)
|
||||
|
@ -100,3 +115,4 @@ bch_sched_event(bchannel_t *bch, int event)
|
|||
schedule_work(&bch->work);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -101,7 +101,6 @@
|
|||
#include "bchannel.h"
|
||||
#include "layer1.h"
|
||||
#include "dsp.h"
|
||||
#include "helper.h"
|
||||
#include "debug.h"
|
||||
#include <linux/isdn_compat.h>
|
||||
|
||||
|
@ -1013,11 +1012,12 @@ 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;
|
||||
mISDN_head_t *hh;
|
||||
if (skb) {
|
||||
dch->next_skb = NULL;
|
||||
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||
hh = mISDN_HEAD_P(skb);
|
||||
dch->tx_idx = 0;
|
||||
dch->tx_len = skb->len;
|
||||
|
@ -1025,8 +1025,10 @@ next_frame:
|
|||
skb_trim(skb, 0);
|
||||
if (mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_CNF, hh->dinfo, skb)) dev_kfree_skb(skb);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
||||
|
@ -1034,28 +1036,23 @@ next_frame:
|
|||
}
|
||||
if (bch) {
|
||||
// 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;
|
||||
mISDN_head_t *hh;
|
||||
u_int pr;
|
||||
if (skb) {
|
||||
bch->next_skb = NULL;
|
||||
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||
hh = mISDN_HEAD_P(skb);
|
||||
bch->tx_idx = 0;
|
||||
bch->tx_len = skb->len;
|
||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||
skb_trim(skb, 0);
|
||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
||||
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);
|
||||
}
|
||||
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||
|
@ -1262,17 +1259,8 @@ next_frame:
|
|||
// schedule D-channel event
|
||||
mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_IND, MISDN_ID_ANY, skb);
|
||||
}
|
||||
if (bch) {
|
||||
// schedule B-channel event
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (bch)
|
||||
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||
*idx = 0;
|
||||
goto next_frame;
|
||||
}
|
||||
|
@ -1301,19 +1289,8 @@ next_frame:
|
|||
//dchannel_sched_event(dch, D_RCVBUFREADY);
|
||||
mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_IND, MISDN_ID_ANY, skb);
|
||||
}
|
||||
if (bch) {
|
||||
// schedule B-channel event
|
||||
//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);
|
||||
}
|
||||
}
|
||||
if (bch)
|
||||
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "bchannel.h"
|
||||
#include "hfc_pci.h"
|
||||
#include "layer1.h"
|
||||
#include "helper.h"
|
||||
#include "debug.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;
|
||||
int new_z2, fcnt, maxlen;
|
||||
u_int pr;
|
||||
struct sk_buff *skb;
|
||||
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 */
|
||||
memcpy(ptr, ptr1, fcnt); /* rest */
|
||||
}
|
||||
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);
|
||||
}
|
||||
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||
}
|
||||
|
||||
*z2r = new_z2; /* new position */
|
||||
|
@ -606,7 +597,6 @@ main_rec_hfcpci(bchannel_t *bch)
|
|||
hfc_pci_t *hc = bch->hw;
|
||||
int rcnt, real_fifo;
|
||||
int receive, count = 5;
|
||||
u_int pr;
|
||||
struct sk_buff *skb;
|
||||
bzfifo_type *bz;
|
||||
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)",
|
||||
bch->channel, zp->z1, zp->z2, rcnt);
|
||||
if ((skb = hfcpci_empty_fifo(bch, bz, bdata, rcnt))) {
|
||||
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);
|
||||
}
|
||||
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||
}
|
||||
rcnt = bz->f1 - bz->f2;
|
||||
if (rcnt < 0)
|
||||
|
@ -814,28 +797,23 @@ next_t_frame:
|
|||
} else if (bch->debug & L1_DEB_HSCX)
|
||||
mISDN_debugprint(&bch->inst, "hfcpci_fill_fifo_trans ch(%x) frame length %d discarded",
|
||||
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;
|
||||
mISDN_head_t *hh;
|
||||
u_int pr;
|
||||
if (skb) {
|
||||
bch->next_skb = NULL;
|
||||
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||
hh = mISDN_HEAD_P(skb);
|
||||
bch->tx_idx = 0;
|
||||
bch->tx_len = skb->len;
|
||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||
skb_trim(skb, 0);
|
||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
||||
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);
|
||||
}
|
||||
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||
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");
|
||||
}
|
||||
}
|
||||
bch->tx_len = 0;
|
||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||
|
@ -1288,28 +1266,22 @@ hfcpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
|
|||
hfcpci_fill_fifo(bch);
|
||||
} else {
|
||||
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;
|
||||
mISDN_head_t *hh;
|
||||
u_int pr;
|
||||
if (skb) {
|
||||
bch->next_skb = NULL;
|
||||
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||
hh = mISDN_HEAD_P(skb);
|
||||
bch->tx_idx = 0;
|
||||
bch->tx_len = skb->len;
|
||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||
skb_trim(skb, 0);
|
||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
||||
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);
|
||||
}
|
||||
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||
hfcpci_fill_fifo(bch);
|
||||
} else {
|
||||
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);
|
||||
bch->tx_len = 0;
|
||||
}
|
||||
|
@ -1330,28 +1302,22 @@ hfcpci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
|
|||
hfcpci_fill_fifo(bch);
|
||||
} else {
|
||||
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;
|
||||
mISDN_head_t *hh;
|
||||
u_int pr;
|
||||
if (skb) {
|
||||
bch->next_skb = NULL;
|
||||
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||
hh = mISDN_HEAD_P(skb);
|
||||
bch->tx_idx = 0;
|
||||
bch->tx_len = skb->len;
|
||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||
skb_trim(skb, 0);
|
||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
||||
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);
|
||||
}
|
||||
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||
hfcpci_fill_fifo(bch);
|
||||
} else {
|
||||
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);
|
||||
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) {
|
||||
hfcpci_fill_dfifo(hc);
|
||||
} else {
|
||||
if (test_and_clear_bit(FLG_TX_NEXT, &hc->dch.DFlags)) {
|
||||
if (hc->dch.next_skb) {
|
||||
mISDN_head_t *hh;
|
||||
hc->dch.tx_len = hc->dch.next_skb->len;
|
||||
memcpy(hc->dch.tx_buf,
|
||||
hc->dch.next_skb->data,
|
||||
hc->dch.tx_len);
|
||||
if (test_bit(FLG_TX_NEXT, &hc->dch.DFlags)) {
|
||||
struct sk_buff *skb = hc->dch.next_skb;
|
||||
if (skb) {
|
||||
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||
|
||||
hc->dch.next_skb= NULL;
|
||||
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;
|
||||
hfcpci_fill_dfifo(hc);
|
||||
skb_trim(hc->dch.next_skb, 0);
|
||||
hh = mISDN_HEAD_P(hc->dch.next_skb);
|
||||
if (mISDN_queueup_newhead(&hc->dch.inst, 0, PH_DATA_CNF, hh->dinfo, hc->dch.next_skb))
|
||||
dev_kfree_skb(hc->dch.next_skb);
|
||||
hc->dch.next_skb= NULL;
|
||||
skb_trim(skb, 0);
|
||||
if (mISDN_queueup_newhead(&hc->dch.inst, 0, PH_DATA_CNF, hh->dinfo, skb))
|
||||
dev_kfree_skb(skb);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
} else
|
||||
|
@ -1432,13 +1399,12 @@ HFCD_l1hw(mISDNinstance_t *inst, struct sk_buff *skb)
|
|||
{
|
||||
dchannel_t *dch;
|
||||
hfc_pci_t *hc;
|
||||
int ret = -EINVAL;
|
||||
int ret = 0;
|
||||
mISDN_head_t *hh;
|
||||
|
||||
hh = mISDN_HEAD_P(skb);
|
||||
dch = container_of(inst, dchannel_t, inst);
|
||||
hc = inst->privat;
|
||||
ret = 0;
|
||||
if (hh->prim == PH_DATA_REQ) {
|
||||
if (dch->next_skb) {
|
||||
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);
|
||||
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
|
||||
del_timer(&dch->dbusytimer);
|
||||
#if 0
|
||||
#ifdef FIXME
|
||||
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
||||
dchannel_sched_event(&hc->dch, D_CLEARBUSY);
|
||||
#endif
|
||||
|
@ -1884,12 +1850,13 @@ hfcpci_l2l1(mISDNinstance_t *inst, struct sk_buff *skb)
|
|||
hh = mISDN_HEAD_P(skb);
|
||||
if ((hh->prim == PH_DATA_REQ) ||
|
||||
(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) {
|
||||
printk(KERN_WARNING "%s: next_skb exist ERROR\n",
|
||||
__FUNCTION__);
|
||||
return(-EBUSY);
|
||||
}
|
||||
if (skb->len <= 0)
|
||||
return(-EINVAL);
|
||||
bch->inst.lock(hc, 0);
|
||||
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
|
||||
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include "dchannel.h"
|
||||
#include "bchannel.h"
|
||||
#include "layer1.h"
|
||||
#include "helper.h"
|
||||
#include "debug.h"
|
||||
#include "hw_lock.h"
|
||||
#include "hfcs_usb.h"
|
||||
|
@ -221,8 +220,8 @@ static struct usb_device_id hfcsusb_idtab[] = {
|
|||
};
|
||||
|
||||
/* some function prototypes */
|
||||
static int hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb);
|
||||
static int hfcsusb_l2l1B(mISDNif_t * hif, struct sk_buff *skb);
|
||||
static int hfcsusb_l1hwD(mISDNinstance_t *inst, 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 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);
|
||||
break;
|
||||
case MGR_UNREGLAYER | REQUEST:
|
||||
if (channel == 2) {
|
||||
inst->down.fdata = &card->dch;
|
||||
if ((skb =
|
||||
create_link_skb(PH_CONTROL | REQUEST,
|
||||
HW_DEACTIVATE, 0,
|
||||
NULL, 0))) {
|
||||
if (hfcsusb_l1hwD
|
||||
(&inst->down, skb))
|
||||
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
||||
HW_DEACTIVATE, 0, NULL, 0))) {
|
||||
if (channel == 2) {
|
||||
if (hfcsusb_l1hwD(inst, skb))
|
||||
dev_kfree_skb(skb);
|
||||
} else {
|
||||
if (hfcsusb_l2l1B(inst, skb))
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
} else {
|
||||
inst->down.fdata = &card->bch[channel];
|
||||
if ((skb =
|
||||
create_link_skb(MGR_DISCONNECT |
|
||||
REQUEST, 0, 0, NULL,
|
||||
0))) {
|
||||
if (hfcsusb_l2l1B
|
||||
(&inst->down, skb))
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
hw_mISDNObj.ctrl(inst->up.peer,
|
||||
MGR_DISCONNECT | REQUEST,
|
||||
&inst->up);
|
||||
hw_mISDNObj.ctrl(inst, MGR_UNREGLAYER | REQUEST,
|
||||
NULL);
|
||||
} else
|
||||
printk(KERN_WARNING "no SKB in %s MGR_UNREGLAYER | REQUEST\n", __FUNCTION__);
|
||||
hw_mISDNObj.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||
break;
|
||||
case MGR_CLRSTPARA | INDICATION:
|
||||
arg = NULL;
|
||||
|
@ -481,40 +466,18 @@ hfcsusb_manager(void *data, u_int prim, void *arg)
|
|||
}
|
||||
*/
|
||||
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:
|
||||
if ((channel != 2) && (inst->pid.global == 2)) {
|
||||
inst->down.fdata = &card->bch[channel];
|
||||
if ((skb =
|
||||
create_link_skb(PH_ACTIVATE | REQUEST,
|
||||
0, 0, NULL, 0))) {
|
||||
if (hfcsusb_l2l1B
|
||||
(&inst->down, skb))
|
||||
if ((skb = create_link_skb(PH_ACTIVATE | REQUEST,
|
||||
0, 0, NULL, 0))) {
|
||||
if (hfcsusb_l2l1B(inst, skb))
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
if (inst->pid.protocol[2] ==
|
||||
ISDN_PID_L2_B_TRANS)
|
||||
if_link(&inst->up,
|
||||
DL_ESTABLISH | INDICATION,
|
||||
if (inst->pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
||||
mISDN_queue_data(inst, FLG_MSG_UP, DL_ESTABLISH | INDICATION,
|
||||
0, 0, NULL, 0);
|
||||
else
|
||||
if_link(&inst->up,
|
||||
PH_ACTIVATE | INDICATION,
|
||||
mISDN_queue_data(inst, FLG_MSG_UP, PH_ACTIVATE | INDICATION,
|
||||
0, 0, NULL, 0);
|
||||
}
|
||||
break;
|
||||
|
@ -547,11 +510,7 @@ S0_new_state(dchannel_t * dch)
|
|||
{
|
||||
u_int prim = PH_SIGNAL | INDICATION;
|
||||
u_int para = 0;
|
||||
mISDNif_t *upif = &dch->inst.up;
|
||||
hfcsusb_t *card = dch->hw;
|
||||
|
||||
if (!test_and_clear_bit(D_L1STATECHANGE, &dch->event))
|
||||
return;
|
||||
hfcsusb_t *card = dch->inst.privat;
|
||||
|
||||
if (card->hw_mode & HW_MODE_TE) {
|
||||
if (dch->debug)
|
||||
|
@ -589,7 +548,7 @@ S0_new_state(dchannel_t * dch)
|
|||
"%s: NT %d",
|
||||
__FUNCTION__, dch->ph_state);
|
||||
|
||||
dch->inst.lock(dch->inst.data, 0);
|
||||
dch->inst.lock(dch->inst.privat, 0);
|
||||
switch (dch->ph_state) {
|
||||
case (1):
|
||||
card->nt_timer = 0;
|
||||
|
@ -610,8 +569,8 @@ S0_new_state(dchannel_t * dch)
|
|||
/* allow G2 -> G3 transition */
|
||||
queued_Write_hfc(card, HFCUSB_STATES, 2 | HFCUSB_NT_G2_G3);
|
||||
}
|
||||
upif = NULL;
|
||||
break;
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
return;
|
||||
case (3):
|
||||
card->nt_timer = 0;
|
||||
card->hw_mode &= ~NT_ACTIVATION_TIMER;
|
||||
|
@ -622,18 +581,14 @@ S0_new_state(dchannel_t * dch)
|
|||
case (4):
|
||||
card->nt_timer = 0;
|
||||
card->hw_mode &= ~NT_ACTIVATION_TIMER;
|
||||
upif = NULL;
|
||||
break;
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
return;
|
||||
default:
|
||||
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;
|
||||
|
||||
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 */
|
||||
|
||||
hfcsusb_t *card = bch->inst.data;
|
||||
hfcsusb_t *card = bch->inst.privat;
|
||||
|
||||
if (bch->debug & L1_DEB_HSCX)
|
||||
mISDN_debugprint(&bch->inst,
|
||||
|
@ -744,10 +699,6 @@ mode_bchannel(bchannel_t * bch, int bc, int protocol)
|
|||
|
||||
if (protocol > ISDN_PID_NONE) {
|
||||
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 {
|
||||
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 */
|
||||
/*************************************/
|
||||
static int
|
||||
hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
||||
hfcsusb_l1hwD(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||
{
|
||||
dchannel_t *dch;;
|
||||
int ret = -EINVAL;
|
||||
mISDN_head_t *hh;
|
||||
hfcsusb_t *card;
|
||||
dchannel_t *dch;
|
||||
int ret = 0;
|
||||
mISDN_head_t *hh;
|
||||
hfcsusb_t *card;
|
||||
|
||||
if (!hif || !skb)
|
||||
return (ret);
|
||||
hh = mISDN_HEAD_P(skb);
|
||||
dch = hif->fdata;
|
||||
card = dch->hw;
|
||||
ret = 0;
|
||||
dch = container_of(inst, dchannel_t, inst);
|
||||
card = inst->privat;
|
||||
|
||||
if (hh->prim == PH_DATA_REQ) {
|
||||
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");
|
||||
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)) {
|
||||
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||
dch->next_skb = skb;
|
||||
dch->inst.unlock(dch->inst.data);
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
return (0);
|
||||
} else {
|
||||
/* prepare buffer, which is transmitted by
|
||||
|
@ -846,22 +794,23 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
|||
dch->tx_len = skb->len;
|
||||
memcpy(dch->tx_buf, skb->data, dch->tx_len);
|
||||
dch->tx_idx = 0;
|
||||
dch->inst.unlock(dch->inst.data);
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
skb_trim(skb, 0);
|
||||
return (if_newhead(&dch->inst.up, PH_DATA_CNF,
|
||||
hh->dinfo, skb));
|
||||
return(mISDN_queueup_newhead(inst, 0, PH_DATA_CNF,
|
||||
hh->dinfo, skb));
|
||||
}
|
||||
} 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)
|
||||
hfcsusb_ph_command(dch->hw, S0_L1CMD_AR8);
|
||||
else if (hh->dinfo == INFO3_P10)
|
||||
hfcsusb_ph_command(dch->hw, S0_L1CMD_AR10);
|
||||
else
|
||||
ret = -EINVAL;
|
||||
dch->inst.unlock(dch->inst.data);
|
||||
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
} 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 (dch->ph_state != 0)
|
||||
hfcsusb_ph_command(dch->hw,
|
||||
|
@ -870,15 +819,16 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
|||
} else if (hh->dinfo == HW_POWERUP) {
|
||||
hfcsusb_ph_command(dch->hw, S0_L1CMD_ECK);
|
||||
} else if (hh->dinfo == HW_DEACTIVATE) {
|
||||
discard_queue(&dch->rqueue);
|
||||
if (dch->next_skb) {
|
||||
dev_kfree_skb(dch->next_skb);
|
||||
dch->next_skb = NULL;
|
||||
}
|
||||
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
|
||||
#ifdef FIXME
|
||||
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
||||
dchannel_sched_event(dch, D_CLEARBUSY);
|
||||
#endif
|
||||
} else if ((hh->dinfo & HW_TESTLOOP) == HW_TESTLOOP) {
|
||||
u_char val = 0;
|
||||
|
||||
|
@ -894,9 +844,9 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
|||
hh->dinfo);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
dch->inst.unlock(dch->inst.data);
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
} 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) {
|
||||
hfcsusb_ph_command(dch->hw, HFC_L1_ACTIVATE_NT);
|
||||
} else {
|
||||
|
@ -905,9 +855,9 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
|||
__FUNCTION__);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
dch->inst.unlock(dch->inst.data);
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
} 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) {
|
||||
hfcsusb_ph_command(dch->hw, HFC_L1_DEACTIVATE_NT);
|
||||
} else {
|
||||
|
@ -916,7 +866,7 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
|||
__FUNCTION__);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
dch->inst.unlock(dch->inst.data);
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
} else {
|
||||
if (dch->debug & L1_DEB_WARN)
|
||||
mISDN_debugprint(&dch->inst,
|
||||
|
@ -933,32 +883,25 @@ hfcsusb_l1hwD(mISDNif_t * hif, struct sk_buff *skb)
|
|||
/* Layer2 -> Layer 1 Transfer */
|
||||
/******************************/
|
||||
static int
|
||||
hfcsusb_l2l1B(mISDNif_t * hif, struct sk_buff *skb)
|
||||
hfcsusb_l2l1B(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||
{
|
||||
bchannel_t *bch;
|
||||
int ret = -EINVAL;
|
||||
mISDN_head_t *hh;
|
||||
|
||||
hfcsusb_t *card;
|
||||
bchannel_t *bch = container_of(inst, bchannel_t, inst);
|
||||
int ret = 0;
|
||||
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||
|
||||
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 (bch->next_skb) {
|
||||
printk(KERN_WARNING "%s: next_skb exist ERROR\n",
|
||||
__FUNCTION__);
|
||||
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)) {
|
||||
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||
bch->next_skb = skb;
|
||||
bch->inst.unlock(bch->inst.data);
|
||||
bch->inst.unlock(bch->inst.privat);
|
||||
return (0);
|
||||
} else {
|
||||
/* prepare buffer, wich is transmitted by
|
||||
|
@ -966,40 +909,39 @@ hfcsusb_l2l1B(mISDNif_t * hif, struct sk_buff *skb)
|
|||
bch->tx_len = skb->len;
|
||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||
bch->tx_idx = 0;
|
||||
bch->inst.unlock(bch->inst.data);
|
||||
if ((bch->inst.pid.protocol[2] ==
|
||||
ISDN_PID_L2_B_RAWDEV)
|
||||
&& bch->dev)
|
||||
bch->inst.unlock(bch->inst.privat);
|
||||
#ifdef FIXME
|
||||
if ((bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
||||
&& bch->dev)
|
||||
hif = &bch->dev->rport.pif;
|
||||
else
|
||||
hif = &bch->inst.up;
|
||||
#endif
|
||||
skb_trim(skb, 0);
|
||||
return (if_newhead(hif, hh->prim | CONFIRM,
|
||||
hh->dinfo, skb));
|
||||
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM,
|
||||
hh->dinfo, skb));
|
||||
}
|
||||
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
|
||||
(hh->prim == (DL_ESTABLISH | REQUEST))) {
|
||||
if (test_and_set_bit(BC_FLG_ACTIV, &bch->Flag))
|
||||
ret = 0;
|
||||
else {
|
||||
bch->inst.lock(bch->inst.data, 0);
|
||||
ret =
|
||||
mode_bchannel(bch, bch->channel,
|
||||
bch->inst.pid.protocol[1]);
|
||||
bch->inst.unlock(bch->inst.data);
|
||||
if (!test_and_set_bit(BC_FLG_ACTIV, &bch->Flag)) {
|
||||
bch->inst.lock(bch->inst.privat, 0);
|
||||
ret = mode_bchannel(bch, bch->channel,
|
||||
bch->inst.pid.protocol[1]);
|
||||
bch->inst.unlock(bch->inst.privat);
|
||||
}
|
||||
#ifdef FIXME
|
||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
||||
if (bch->dev)
|
||||
if_link(&bch->dev->rport.pif,
|
||||
hh->prim | CONFIRM, 0, 0, NULL, 0);
|
||||
#endif
|
||||
skb_trim(skb, 0);
|
||||
return (if_newhead
|
||||
(&bch->inst.up, hh->prim | CONFIRM, ret, skb));
|
||||
} else if ((hh->prim == (PH_DEACTIVATE | REQUEST))
|
||||
|| (hh->prim == (DL_RELEASE | REQUEST))
|
||||
|| (hh->prim == (MGR_DISCONNECT | REQUEST))) {
|
||||
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, ret, skb));
|
||||
} else if ((hh->prim == (PH_DEACTIVATE | REQUEST)) ||
|
||||
(hh->prim == (DL_RELEASE | 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)) {
|
||||
dev_kfree_skb(bch->next_skb);
|
||||
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);
|
||||
mode_bchannel(bch, bch->channel, ISDN_PID_NONE);
|
||||
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);
|
||||
if (hh->prim != (MGR_DISCONNECT | REQUEST)) {
|
||||
if (bch->inst.pid.protocol[2] ==
|
||||
ISDN_PID_L2_B_RAWDEV)
|
||||
if (hh->prim != (PH_CONTROL | REQUEST)) {
|
||||
#ifdef FIXME
|
||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
||||
if (bch->dev)
|
||||
if_link(&bch->dev->rport.pif,
|
||||
hh->prim | CONFIRM, 0, 0,
|
||||
NULL, 0);
|
||||
if (!if_newhead
|
||||
(&bch->inst.up, hh->prim | CONFIRM, 0, skb))
|
||||
return (0);
|
||||
hh->prim | CONFIRM, 0, 0, NULL, 0);
|
||||
#endif
|
||||
if (!mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, 0, skb))
|
||||
return(0);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
||||
// do not handle PH_CONTROL | REQUEST ??
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
printk(KERN_WARNING "%s: unknown prim(%x)\n",
|
||||
__FUNCTION__, hh->prim);
|
||||
__FUNCTION__, hh->prim);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (!ret)
|
||||
dev_kfree_skb(skb);
|
||||
|
@ -1039,11 +980,11 @@ hfcsusb_l2l1B(mISDNif_t * hif, struct sk_buff *skb)
|
|||
static void
|
||||
collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
|
||||
{
|
||||
hfcsusb_t *card = fifo->card;
|
||||
struct sk_buff *skb;
|
||||
u_char *ptr;
|
||||
int fifon;
|
||||
int i;
|
||||
hfcsusb_t *card = fifo->card;
|
||||
struct sk_buff *skb;
|
||||
u_char *ptr;
|
||||
int fifon;
|
||||
int i;
|
||||
|
||||
fifon = fifo->fifonum;
|
||||
|
||||
|
@ -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 (fifo->skbuff->len >= 128) {
|
||||
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");
|
||||
else {
|
||||
ptr =
|
||||
skb_put(skb,
|
||||
fifo->skbuff->
|
||||
len);
|
||||
memcpy(ptr, fifo->skbuff->data,
|
||||
fifo->skbuff->len);
|
||||
ptr = skb_put(skb, fifo->skbuff->len);
|
||||
memcpy(ptr, fifo->skbuff->data, fifo->skbuff->len);
|
||||
dev_kfree_skb(fifo->skbuff);
|
||||
fifo->skbuff=NULL;
|
||||
|
||||
skb_queue_tail(&card->bch[fifo->bch_idx].
|
||||
rqueue,
|
||||
skb);
|
||||
|
||||
bch_sched_event(&card->bch[fifo->bch_idx], B_RCVBUFREADY);
|
||||
queue_bch_frame(&card->bch[fifo->bch_idx],
|
||||
INDICATION, MISDN_ID_ANY, skb);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -1115,28 +1048,15 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
|
|||
|
||||
switch (fifon) {
|
||||
case HFCUSB_D_RX:
|
||||
if ((skb =
|
||||
alloc_stack_skb(fifo->skbuff->
|
||||
len,
|
||||
card->dch.
|
||||
up_headerlen)))
|
||||
{
|
||||
ptr =
|
||||
skb_put(skb,
|
||||
fifo->skbuff->
|
||||
len);
|
||||
memcpy(ptr, fifo->skbuff->data, fifo->skbuff->len);
|
||||
if ((skb = alloc_stack_skb(fifo->skbuff->len,
|
||||
card->dch.up_headerlen))) {
|
||||
ptr = skb_put(skb, fifo->skbuff->len);
|
||||
memcpy(ptr, fifo->skbuff->data,
|
||||
fifo->skbuff->len);
|
||||
dev_kfree_skb(fifo->skbuff);
|
||||
fifo->skbuff=NULL;
|
||||
|
||||
skb_queue_tail(&card->dch.
|
||||
rqueue,
|
||||
skb);
|
||||
|
||||
dchannel_sched_event
|
||||
(&card->dch,
|
||||
D_RCVBUFREADY);
|
||||
|
||||
mISDN_queueup_newhead(&card->dch.inst, 0,
|
||||
PH_DATA_IND, MISDN_ID_ANY, skb);
|
||||
} else {
|
||||
printk(KERN_WARNING
|
||||
"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_B2_RX:
|
||||
if (card->bch[fifo->bch_idx].protocol > ISDN_PID_NONE) {
|
||||
if ((skb =
|
||||
alloc_stack_skb(fifo->skbuff->
|
||||
len,
|
||||
card->
|
||||
bch[fifo->bch_idx].
|
||||
up_headerlen)))
|
||||
if ((skb = alloc_stack_skb(fifo->skbuff->len,
|
||||
card->bch[fifo->bch_idx].up_headerlen)))
|
||||
{
|
||||
ptr =
|
||||
skb_put(skb,
|
||||
fifo->skbuff->
|
||||
len);
|
||||
ptr = skb_put(skb, fifo->skbuff->len);
|
||||
memcpy(ptr, fifo->skbuff->data, fifo->skbuff->len);
|
||||
dev_kfree_skb(fifo->skbuff);
|
||||
fifo->skbuff=NULL;
|
||||
|
||||
skb_queue_tail(&card->
|
||||
bch
|
||||
[fifo->bch_idx].
|
||||
rqueue,
|
||||
skb);
|
||||
bch_sched_event(&card->
|
||||
bch
|
||||
[fifo->bch_idx],
|
||||
B_RCVBUFREADY);
|
||||
queue_bch_frame(&card->bch[fifo->bch_idx],
|
||||
INDICATION, MISDN_ID_ANY, skb);
|
||||
} else {
|
||||
printk(KERN_WARNING
|
||||
"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
|
||||
next_d_tx_frame(hfcsusb_t * card)
|
||||
{
|
||||
if (test_and_clear_bit(FLG_TX_NEXT, &card->dch.DFlags)) {
|
||||
if (card->dch.next_skb) {
|
||||
card->dch.tx_len = card->dch.next_skb->len;
|
||||
memcpy(card->dch.tx_buf,
|
||||
card->dch.next_skb->data, card->dch.tx_len);
|
||||
if (test_bit(FLG_TX_NEXT, &card->dch.DFlags)) {
|
||||
struct sk_buff *skb = card->dch.next_skb;
|
||||
if (skb) {
|
||||
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||
|
||||
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;
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
} else
|
||||
|
@ -1391,20 +1302,23 @@ next_d_tx_frame(hfcsusb_t * card)
|
|||
void
|
||||
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 (card->bch[bch_idx].next_skb) {
|
||||
if (test_bit(BC_FLG_TX_NEXT, &card->bch[bch_idx].Flag)) {
|
||||
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_len =
|
||||
card->bch[bch_idx].next_skb->len;
|
||||
memcpy(card->bch[bch_idx].tx_buf,
|
||||
card->bch[bch_idx].next_skb->data,
|
||||
card->bch[bch_idx].tx_len);
|
||||
bch_sched_event(&card->bch[bch_idx],
|
||||
B_XMTBUFREADY);
|
||||
} else
|
||||
card->bch[bch_idx].tx_len = skb->len;
|
||||
memcpy(card->bch[bch_idx].tx_buf, skb->data, card->bch[bch_idx].tx_len);
|
||||
|
||||
queue_bch_frame(&card->bch[bch_idx], CONFIRM, hh->dinfo, skb);
|
||||
} else {
|
||||
printk(KERN_WARNING
|
||||
"hfc B%i tx irq TX_NEXT without skb\n",
|
||||
bch_idx);
|
||||
"hfc B%i tx irq TX_NEXT without skb\n", 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)
|
||||
&& (card->hw_mode & NT_ACTIVATION_TIMER)) {
|
||||
if ((--card->nt_timer) < 0)
|
||||
dchannel_sched_event(&card->dch, D_L1STATECHANGE);
|
||||
S0_new_state(&card->dch);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -1882,8 +1796,6 @@ release_card(hfcsusb_t * card)
|
|||
mISDN_free_bch(&card->bch[1]);
|
||||
mISDN_free_bch(&card->bch[0]);
|
||||
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);
|
||||
list_del(&card->list);
|
||||
unlock_dev(card);
|
||||
|
@ -1934,7 +1846,7 @@ setup_instance(hfcsusb_t * card)
|
|||
card->dch.inst.unlock = unlock_dev;
|
||||
card->dch.inst.pid.layermask = ISDN_LAYER(0);
|
||||
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);
|
||||
mISDN_set_dchannel_pid(&pid, protocol[hfcsusb_cnt],
|
||||
layermask[hfcsusb_cnt]);
|
||||
|
@ -1944,8 +1856,7 @@ setup_instance(hfcsusb_t * card)
|
|||
|
||||
for (i = 0; i < 2; i++) {
|
||||
card->bch[i].channel = i;
|
||||
mISDN_init_instance(&card->bch[i].inst, &hw_mISDNObj,
|
||||
card);
|
||||
mISDN_init_instance(&card->bch[i].inst, &hw_mISDNObj, card, hfcsusb_l2l1B);
|
||||
card->bch[i].inst.pid.layermask = ISDN_LAYER(0);
|
||||
card->bch[i].inst.lock = lock_dev;
|
||||
card->bch[i].inst.unlock = unlock_dev;
|
||||
|
@ -1954,10 +1865,12 @@ setup_instance(hfcsusb_t * card)
|
|||
card->dch.inst.name, i + 1);
|
||||
mISDN_init_bch(&card->bch[i]);
|
||||
card->bch[i].hw = card;
|
||||
#ifdef FIXME
|
||||
if (card->bch[i].dev) {
|
||||
card->bch[i].dev->wport.pif.func = hfcsusb_l2l1B;
|
||||
card->bch[i].dev->wport.pif.fdata = &card->bch[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (protocol[hfcsusb_cnt] & 0x10) {
|
||||
|
|
|
@ -243,16 +243,16 @@ isac_xpr_irq(dchannel_t *dch)
|
|||
if (dch->tx_idx < dch->tx_len) {
|
||||
isac_fill_fifo(dch);
|
||||
} else {
|
||||
if (test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||
struct sk_buff *skb;
|
||||
mISDN_head_t *hh;
|
||||
if ((skb = dch->next_skb)) {
|
||||
if (test_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||
struct sk_buff *skb = dch->next_skb;
|
||||
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||
if (skb) {
|
||||
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;
|
||||
isac_fill_fifo(dch);
|
||||
hh = mISDN_HEAD_P(skb);
|
||||
skb_trim(skb, 0);
|
||||
if (unlikely(mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_CNF, hh->dinfo, skb))) {
|
||||
int_error();
|
||||
|
@ -260,6 +260,7 @@ isac_xpr_irq(dchannel_t *dch)
|
|||
}
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
} else
|
||||
|
@ -283,11 +284,12 @@ isac_retransmit(dchannel_t *dch)
|
|||
} else {
|
||||
printk(KERN_WARNING "mISDN: ISAC XDU no TX_BUSY\n");
|
||||
mISDN_debugprint(&dch->inst, "ISAC XDU no TX_BUSY");
|
||||
if (test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||
struct sk_buff *skb;
|
||||
mISDN_head_t *hh;
|
||||
if ((skb = dch->next_skb)) {
|
||||
if (test_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||
struct sk_buff *skb = dch->next_skb;
|
||||
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||
if (skb) {
|
||||
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;
|
||||
|
@ -300,6 +302,7 @@ isac_retransmit(dchannel_t *dch)
|
|||
}
|
||||
} else {
|
||||
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 "layer1.h"
|
||||
#include "helper.h"
|
||||
#include "bchannel.h"
|
||||
#include "isar.h"
|
||||
#include "debug.h"
|
||||
|
@ -462,7 +461,6 @@ isar_rcv_frame(bchannel_t *bch)
|
|||
{
|
||||
u_char *ptr;
|
||||
struct sk_buff *skb;
|
||||
u_int pr;
|
||||
isar_hw_t *ih = bch->hw;
|
||||
|
||||
if (!ih->reg->clsb) {
|
||||
|
@ -483,14 +481,7 @@ isar_rcv_frame(bchannel_t *bch)
|
|||
case ISDN_PID_L1_B_MODEM_ASYNC:
|
||||
if ((skb = alloc_stack_skb(ih->reg->clsb, bch->up_headerlen))) {
|
||||
rcv_mbox(bch, ih->reg, (u_char *)skb_put(skb, ih->reg->clsb));
|
||||
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);
|
||||
}
|
||||
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||
} else {
|
||||
printk(KERN_WARNING "mISDN: skb out of memory\n");
|
||||
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
|
||||
|
@ -530,14 +521,7 @@ isar_rcv_frame(bchannel_t *bch)
|
|||
} else {
|
||||
memcpy(skb_put(skb, bch->rx_idx-2),
|
||||
bch->rx_buf, bch->rx_idx-2);
|
||||
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);
|
||||
}
|
||||
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||
}
|
||||
bch->rx_idx = 0;
|
||||
}
|
||||
|
@ -569,14 +553,7 @@ isar_rcv_frame(bchannel_t *bch)
|
|||
ih->state = STFAX_ESCAPE;
|
||||
// set_skb_flag(skb, DF_NOMOREDATA);
|
||||
}
|
||||
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);
|
||||
}
|
||||
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||
if (ih->reg->cmsb & SART_NMD)
|
||||
deliver_status(bch, HW_MOD_NOCARR);
|
||||
} else {
|
||||
|
@ -623,14 +600,7 @@ isar_rcv_frame(bchannel_t *bch)
|
|||
// if (ih->reg->cmsb & SART_NMD)
|
||||
/* ABORT */
|
||||
// set_skb_flag(skb, DF_NOMOREDATA);
|
||||
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);
|
||||
}
|
||||
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
|
||||
}
|
||||
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;
|
||||
mISDN_head_t *hh;
|
||||
u_int pr;
|
||||
if (skb) {
|
||||
bch->next_skb = NULL;
|
||||
test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||
hh = mISDN_HEAD_P(skb);
|
||||
bch->tx_idx = 0;
|
||||
bch->tx_len = skb->len;
|
||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||
isar_fill_fifo(bch);
|
||||
skb_trim(skb, 0);
|
||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
|
||||
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);
|
||||
}
|
||||
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||
} else {
|
||||
bch->tx_len = 0;
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
|
@ -1597,18 +1561,19 @@ int
|
|||
isar_down(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||
{
|
||||
bchannel_t *bch;
|
||||
int ret = -EINVAL;
|
||||
int ret = 0;
|
||||
mISDN_head_t *hh;
|
||||
|
||||
hh = mISDN_HEAD_P(skb);
|
||||
bch = container_of(inst, bchannel_t, inst);
|
||||
ret = 0;
|
||||
if ((hh->prim == PH_DATA_REQ) ||
|
||||
(hh->prim == (DL_DATA | REQUEST))) {
|
||||
if (bch->next_skb) {
|
||||
mISDN_debugprint(&bch->inst, " l2l1 next_skb exist this shouldn't happen");
|
||||
return(-EBUSY);
|
||||
}
|
||||
if (skb->len <= 0)
|
||||
return(-EINVAL);
|
||||
bch->inst.lock(bch->inst.privat, 0);
|
||||
if (test_and_set_bit(BC_FLG_TX_BUSY, &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)) ||
|
||||
(hh->prim == (DL_ESTABLISH | REQUEST))) {
|
||||
if (test_and_set_bit(BC_FLG_ACTIV, &bch->Flag))
|
||||
ret = 0;
|
||||
else {
|
||||
if (!test_and_set_bit(BC_FLG_ACTIV, &bch->Flag)) {
|
||||
u_int bp = bch->inst.pid.protocol[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);
|
||||
skb_trim(skb, 0);
|
||||
if (hh->prim != (PH_CONTROL | REQUEST))
|
||||
if (!mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, 0, skb))
|
||||
return(0);
|
||||
ret = mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, 0, skb);
|
||||
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
||||
int *val;
|
||||
int len;
|
||||
|
@ -1704,6 +1666,7 @@ isar_down(mISDNinstance_t *inst, struct sk_buff *skb)
|
|||
int_errtxt("wrong modulation");
|
||||
/* wrong modulation or not activ */
|
||||
// TODO
|
||||
ret = -EINVAL;
|
||||
}
|
||||
} else if (hh->dinfo == HW_MOD_LASTDATA) {
|
||||
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 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) {
|
||||
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);
|
||||
dch->inst.unlock(dch->inst.data);
|
||||
prim = PH_CONTROL | INDICATION;
|
||||
para = HW_RESET;
|
||||
while(upif) {
|
||||
if_link(upif, prim, para, 0, NULL, 0);
|
||||
upif = upif->clone;
|
||||
}
|
||||
upif = &dch->inst.up;
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
mISDN_queue_data(&dch->inst, FLG_MSG_UP, PH_CONTROL | INDICATION, HW_RESET, 0, NULL, 0);
|
||||
/* fall trough */
|
||||
case W_L1IND_CD:
|
||||
prim = PH_CONTROL | CONFIRM;
|
||||
|
@ -195,10 +184,7 @@ W6692_new_ph(dchannel_t *dch)
|
|||
default:
|
||||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -281,8 +267,10 @@ d_retransmit(w6692pci *card)
|
|||
|
||||
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
|
||||
del_timer(&dch->dbusytimer);
|
||||
#ifdef FIXME
|
||||
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
||||
dchannel_sched_event(dch, D_CLEARBUSY);
|
||||
#endif
|
||||
if (test_bit(FLG_TX_BUSY, &dch->DFlags)) {
|
||||
/* Restart frame */
|
||||
dch->tx_idx = 0;
|
||||
|
@ -290,17 +278,22 @@ d_retransmit(w6692pci *card)
|
|||
} else {
|
||||
printk(KERN_WARNING "mISDN: w6692 XDU no TX_BUSY\n");
|
||||
mISDN_debugprint(&dch->inst, "XDU no TX_BUSY");
|
||||
if (test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||
if (dch->next_skb) {
|
||||
dch->tx_len = dch->next_skb->len;
|
||||
memcpy(dch->tx_buf,
|
||||
dch->next_skb->data,
|
||||
dch->tx_len);
|
||||
if (test_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||
struct sk_buff *skb = dch->next_skb;
|
||||
if (skb) {
|
||||
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||
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;
|
||||
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 {
|
||||
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)
|
||||
count = W_D_FIFO_THRESH;
|
||||
W6692_empty_Dfifo(card, count);
|
||||
if (card->dch.rx_skb) {
|
||||
skb_queue_tail(&card->dch.rqueue, card->dch.rx_skb);
|
||||
}
|
||||
if (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;
|
||||
dchannel_sched_event(&card->dch, D_RCVBUFREADY);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -356,21 +348,29 @@ handle_txD(w6692pci *card) {
|
|||
|
||||
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
|
||||
del_timer(&dch->dbusytimer);
|
||||
#ifdef FIXME
|
||||
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
||||
dchannel_sched_event(dch, D_CLEARBUSY);
|
||||
#endif
|
||||
if (dch->tx_idx < dch->tx_len) {
|
||||
W6692_fill_Dfifo(card);
|
||||
} else {
|
||||
if (test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||
if (dch->next_skb) {
|
||||
dch->tx_len = dch->next_skb->len;
|
||||
memcpy(dch->tx_buf,
|
||||
dch->next_skb->data, dch->tx_len);
|
||||
if (test_bit(FLG_TX_NEXT, &dch->DFlags)) {
|
||||
struct sk_buff *skb = dch->next_skb;
|
||||
if (skb) {
|
||||
mISDN_head_t *hh = mISDN_HEAD_P(skb);
|
||||
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;
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
} else
|
||||
|
@ -431,7 +431,7 @@ handle_statusD(w6692pci *card) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
dchannel_sched_event(dch, D_L1STATECHANGE);
|
||||
W6692_new_ph(dch);
|
||||
}
|
||||
if (cir & W_CIR_SCC) {
|
||||
v1 = ReadW6692(card, W_SQR);
|
||||
|
@ -453,7 +453,7 @@ static void
|
|||
W6692_empty_Bfifo(bchannel_t *bch, int count)
|
||||
{
|
||||
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))
|
||||
mISDN_debugprint(&bch->inst, "empty_Bfifo %d", count);
|
||||
|
@ -488,7 +488,7 @@ W6692_empty_Bfifo(bchannel_t *bch, int count)
|
|||
static void
|
||||
W6692_fill_Bfifo(bchannel_t *bch)
|
||||
{
|
||||
w6692pci *card = bch->inst.data;
|
||||
w6692pci *card = bch->inst.privat;
|
||||
int count;
|
||||
u_char *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS;
|
||||
|
||||
|
@ -523,7 +523,7 @@ W6692_fill_Bfifo(bchannel_t *bch)
|
|||
static int
|
||||
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;
|
||||
u_char val;
|
||||
|
||||
|
@ -550,7 +550,7 @@ static int
|
|||
enable_pots(bchannel_t *bch)
|
||||
{
|
||||
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))
|
||||
return(-ENODEV);
|
||||
|
@ -567,7 +567,7 @@ static int
|
|||
disable_pots(bchannel_t *bch)
|
||||
{
|
||||
w6692_bc *bhw = bch->hw;
|
||||
w6692pci *card = bch->inst.data;
|
||||
w6692pci *card = bch->inst.privat;
|
||||
|
||||
if (card->pots == 0)
|
||||
return(-ENODEV);
|
||||
|
@ -580,7 +580,7 @@ disable_pots(bchannel_t *bch)
|
|||
static int
|
||||
mode_w6692(bchannel_t *bch, int bc, int protocol)
|
||||
{
|
||||
w6692pci *card = bch->inst.data;
|
||||
w6692pci *card = bch->inst.privat;
|
||||
w6692_bc *bhw = bch->hw;
|
||||
|
||||
|
||||
|
@ -605,7 +605,6 @@ mode_w6692(bchannel_t *bch, int bc, int protocol)
|
|||
dev_kfree_skb(bch->next_skb);
|
||||
bch->next_skb = NULL;
|
||||
}
|
||||
discard_queue(&bch->rqueue);
|
||||
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);
|
||||
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_EXIM, 0);
|
||||
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;
|
||||
case (ISDN_PID_L1_B_64HDLC):
|
||||
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_EXIM, 0);
|
||||
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;
|
||||
default:
|
||||
mISDN_debugprint(&bch->inst, "prot not known %x", protocol);
|
||||
|
@ -643,13 +640,21 @@ send_next(bchannel_t *bch)
|
|||
W6692_fill_Bfifo(bch);
|
||||
else {
|
||||
bch->tx_idx = 0;
|
||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||
if (bch->next_skb) {
|
||||
bch->tx_len = bch->next_skb->len;
|
||||
memcpy(bch->tx_buf, bch->next_skb->data, bch->tx_len);
|
||||
if (test_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||
struct sk_buff *skb = bch->next_skb;
|
||||
if (skb) {
|
||||
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);
|
||||
skb_trim(skb, 0);
|
||||
queue_bch_frame(bch, CONFIRM, hh->dinfo, skb);
|
||||
} else {
|
||||
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");
|
||||
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
|
||||
}
|
||||
|
@ -657,7 +662,6 @@ send_next(bchannel_t *bch)
|
|||
bch->tx_len = 0;
|
||||
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");
|
||||
else {
|
||||
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;
|
||||
|
@ -739,9 +742,8 @@ W6692B_interrupt(w6692pci *card, int ch)
|
|||
printk(KERN_WARNING "Bchan receive out of memory\n");
|
||||
else {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -887,7 +889,7 @@ dbusy_timer_handler(dchannel_t *dch)
|
|||
int rbch, star;
|
||||
|
||||
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;
|
||||
add_timer(&dch->dbusytimer);
|
||||
return;
|
||||
|
@ -911,7 +913,7 @@ dbusy_timer_handler(dchannel_t *dch)
|
|||
/* 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 */
|
||||
/******************************/
|
||||
static int
|
||||
w6692_l2l1B(mISDNif_t *hif, struct sk_buff *skb)
|
||||
w6692_l2l1B(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||
{
|
||||
bchannel_t *bch;
|
||||
int ret = -EINVAL;
|
||||
mISDN_head_t *hh;
|
||||
bchannel_t *bch = container_of(inst, bchannel_t, inst);
|
||||
int ret = 0;
|
||||
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) ||
|
||||
(hh->prim == (DL_DATA | REQUEST))) {
|
||||
if (bch->next_skb) {
|
||||
|
@ -1053,46 +1051,50 @@ w6692_l2l1B(mISDNif_t *hif, struct sk_buff *skb)
|
|||
__FUNCTION__);
|
||||
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)) {
|
||||
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
|
||||
bch->next_skb = skb;
|
||||
bch->inst.unlock(bch->inst.data);
|
||||
bch->inst.unlock(bch->inst.privat);
|
||||
return(0);
|
||||
} else {
|
||||
bch->tx_len = skb->len;
|
||||
memcpy(bch->tx_buf, skb->data, bch->tx_len);
|
||||
bch->tx_idx = 0;
|
||||
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)
|
||||
&& bch->dev)
|
||||
hif = &bch->dev->rport.pif;
|
||||
else
|
||||
hif = &bch->inst.up;
|
||||
#endif
|
||||
skb_trim(skb, 0);
|
||||
return(if_newhead(hif, hh->prim | CONFIRM,
|
||||
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM,
|
||||
hh->dinfo, skb));
|
||||
}
|
||||
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
|
||||
(hh->prim == (DL_ESTABLISH | REQUEST))) {
|
||||
if (test_and_set_bit(BC_FLG_ACTIV, &bch->Flag))
|
||||
ret = 0;
|
||||
else {
|
||||
bch->inst.lock(bch->inst.data, 0);
|
||||
if (!test_and_set_bit(BC_FLG_ACTIV, &bch->Flag)) {
|
||||
bch->inst.lock(bch->inst.privat, 0);
|
||||
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->dev)
|
||||
if_link(&bch->dev->rport.pif,
|
||||
hh->prim | CONFIRM, 0, 0, NULL, 0);
|
||||
#endif
|
||||
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)) ||
|
||||
(hh->prim == (DL_RELEASE | REQUEST)) ||
|
||||
(hh->prim == (MGR_DISCONNECT | REQUEST))) {
|
||||
bch->inst.lock(bch->inst.data, 0);
|
||||
(hh->prim == (DL_RELEASE | REQUEST)) ||
|
||||
((hh->prim == (PH_CONTROL | REQUEST) && (hh->dinfo == HW_DEACTIVATE)))) {
|
||||
bch->inst.lock(bch->inst.privat, 0);
|
||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||
dev_kfree_skb(bch->next_skb);
|
||||
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);
|
||||
mode_w6692(bch, bch->channel, ISDN_PID_NONE);
|
||||
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);
|
||||
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->dev)
|
||||
if_link(&bch->dev->rport.pif,
|
||||
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);
|
||||
}
|
||||
ret = 0;
|
||||
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
||||
ret = 0;
|
||||
bch->inst.lock(bch->inst.data, 0);
|
||||
bch->inst.lock(bch->inst.privat, 0);
|
||||
if (hh->dinfo == HW_POTS_ON) {
|
||||
ret = enable_pots(bch);
|
||||
} 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);
|
||||
} else
|
||||
ret = -EINVAL;
|
||||
bch->inst.unlock(bch->inst.data);
|
||||
bch->inst.unlock(bch->inst.privat);
|
||||
} else {
|
||||
printk(KERN_WARNING "%s: unknown prim(%x)\n",
|
||||
__FUNCTION__, hh->prim);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (!ret)
|
||||
dev_kfree_skb(skb);
|
||||
|
@ -1135,48 +1138,43 @@ w6692_l2l1B(mISDNif_t *hif, struct sk_buff *skb)
|
|||
}
|
||||
|
||||
static int
|
||||
w6692_l1hwD(mISDNif_t *hif, struct sk_buff *skb)
|
||||
w6692_l1hwD(mISDNinstance_t *inst, struct sk_buff *skb)
|
||||
{
|
||||
dchannel_t *dch;
|
||||
int ret = -EINVAL;
|
||||
mISDN_head_t *hh;
|
||||
dchannel_t *dch = container_of(inst, dchannel_t, inst);
|
||||
int ret = 0;
|
||||
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 (dch->next_skb) {
|
||||
mISDN_debugprint(&dch->inst, "w6692 l2l1 next_skb exist this shouldn't happen");
|
||||
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)) {
|
||||
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
|
||||
dch->next_skb = skb;
|
||||
dch->inst.unlock(dch->inst.data);
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
return(0);
|
||||
} else {
|
||||
dch->tx_len = skb->len;
|
||||
memcpy(dch->tx_buf, skb->data, dch->tx_len);
|
||||
dch->tx_idx = 0;
|
||||
W6692_fill_Dfifo(dch->hw);
|
||||
dch->inst.unlock(dch->inst.data);
|
||||
return(if_newhead(&dch->inst.up, PH_DATA_CNF,
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
return(mISDN_queueup_newhead(inst, 0, PH_DATA_CNF,
|
||||
hh->dinfo, skb));
|
||||
}
|
||||
} 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)
|
||||
ph_command(dch->hw, W_L1CMD_AR8);
|
||||
else if (hh->dinfo == INFO3_P10)
|
||||
ph_command(dch->hw, W_L1CMD_AR10);
|
||||
else
|
||||
ret = -EINVAL;
|
||||
dch->inst.unlock(dch->inst.data);
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
} 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 (dch->ph_state != W_L1IND_DRD)
|
||||
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) {
|
||||
ph_command(dch->hw, W_L1CMD_ECK);
|
||||
} else if (hh->dinfo == HW_DEACTIVATE) {
|
||||
discard_queue(&dch->rqueue);
|
||||
if (dch->next_skb) {
|
||||
dev_kfree_skb(dch->next_skb);
|
||||
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);
|
||||
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
|
||||
del_timer(&dch->dbusytimer);
|
||||
#ifdef FIXME
|
||||
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
|
||||
dchannel_sched_event(dch, D_CLEARBUSY);
|
||||
#endif
|
||||
} else if ((hh->dinfo & HW_TESTLOOP) == HW_TESTLOOP) {
|
||||
u_char val = 0;
|
||||
|
||||
|
@ -1209,7 +1208,7 @@ w6692_l1hwD(mISDNif_t *hif, struct sk_buff *skb)
|
|||
hh->dinfo);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
dch->inst.unlock(dch->inst.data);
|
||||
dch->inst.unlock(dch->inst.privat);
|
||||
} else {
|
||||
if (dch->debug & L1_DEB_WARN)
|
||||
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[0]);
|
||||
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);
|
||||
list_del(&card->list);
|
||||
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);
|
||||
break;
|
||||
case MGR_UNREGLAYER | REQUEST:
|
||||
if (channel == 2) {
|
||||
inst->down.fdata = &card->dch;
|
||||
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
||||
HW_DEACTIVATE, 0, NULL, 0))) {
|
||||
if (w6692_l1hwD(&inst->down, skb))
|
||||
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
||||
HW_DEACTIVATE, 0, NULL, 0))) {
|
||||
if (channel == 2) {
|
||||
if (w6692_l1hwD(inst, skb))
|
||||
dev_kfree_skb(skb);
|
||||
} else {
|
||||
if (w6692_l2l1B(inst, skb))
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
} else {
|
||||
inst->down.fdata = &card->bch[channel];
|
||||
if ((skb = create_link_skb(MGR_DISCONNECT | REQUEST,
|
||||
0, 0, NULL, 0))) {
|
||||
if (w6692_l2l1B(&inst->down, skb))
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
w6692.ctrl(inst->up.peer, MGR_DISCONNECT | REQUEST, &inst->up);
|
||||
} else
|
||||
printk(KERN_WARNING "no SKB in %s MGR_UNREGLAYER | REQUEST\n", __FUNCTION__);
|
||||
w6692.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||
break;
|
||||
case MGR_CLRSTPARA | INDICATION:
|
||||
|
@ -1361,33 +1354,18 @@ w6692_manager(void *data, u_int prim, void *arg) {
|
|||
w6692.refcnt--;
|
||||
}
|
||||
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:
|
||||
if ((channel!=2) && (inst->pid.global == 2)) {
|
||||
inst->down.fdata = &card->bch[channel];
|
||||
if ((skb = create_link_skb(PH_ACTIVATE | REQUEST,
|
||||
0, 0, NULL, 0))) {
|
||||
if (w6692_l2l1B(&inst->down, skb))
|
||||
if (w6692_l2l1B(inst, skb))
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
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);
|
||||
else
|
||||
if_link(&inst->up, PH_ACTIVATE | INDICATION,
|
||||
mISDN_queue_data(inst, FLG_MSG_UP, PH_ACTIVATE | INDICATION,
|
||||
0, 0, NULL, 0);
|
||||
}
|
||||
break;
|
||||
|
@ -1425,14 +1403,14 @@ static int __devinit setup_instance(w6692pci *card)
|
|||
card->dch.inst.unlock = unlock_dev;
|
||||
card->dch.inst.pid.layermask = ISDN_LAYER(0);
|
||||
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);
|
||||
mISDN_set_dchannel_pid(&pid, protocol[w6692_cnt], layermask[w6692_cnt]);
|
||||
mISDN_init_dch(&card->dch);
|
||||
card->dch.hw = card;
|
||||
for (i=0; i<2; 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.lock = lock_dev;
|
||||
card->bch[i].inst.unlock = unlock_dev;
|
||||
|
|
Loading…
Reference in New Issue