- common HW layer channel model for B and D channel

* reduce duplicated code
  * not finished and tested for all drivers
This commit is contained in:
Karsten Keil 2005-12-08 18:32:53 +00:00
parent e1b97ac317
commit 0913082112
25 changed files with 2860 additions and 3724 deletions

View File

@ -69,7 +69,7 @@ hfcmulti-objs := hfc_multi.o
xhfc-objs := xhfc_su.o xhfc_pci2pi.o
mISDN_isac-objs := isac.o arcofi.o
mISDN_core-objs := core.o stack.o udevice.o helper.o debug.o fsm.o \
dchannel.o bchannel.o l3helper.o \
channel.o l3helper.o \
sysfs_obj.o sysfs_inst.o sysfs_st.o
ifdef CONFIG_MISDN_MEMDEBUG
mISDN_core-objs += memdbg.o

View File

@ -8,7 +8,7 @@
*
*/
#include "dchannel.h"
#include "channel.h"
#include "layer1.h"
#include "isac.h"
#include "arcofi.h"
@ -18,10 +18,10 @@
#define ARCOFI_TIMER_VALUE 20
static void
add_arcofi_timer(dchannel_t *dch) {
add_arcofi_timer(channel_t *dch) {
isac_chip_t *isac = dch->hw;
if (test_and_set_bit(FLG_ARCOFI_TIMER, &dch->DFlags)) {
if (test_and_set_bit(FLG_ARCOFI_TIMER, &dch->Flags)) {
del_timer(&isac->arcofitimer);
}
init_timer(&isac->arcofitimer);
@ -30,7 +30,7 @@ add_arcofi_timer(dchannel_t *dch) {
}
static void
send_arcofi(dchannel_t *dch) {
send_arcofi(channel_t *dch) {
u_char val;
isac_chip_t *isac = dch->hw;
@ -54,7 +54,7 @@ send_arcofi(dchannel_t *dch) {
}
int
arcofi_fsm(dchannel_t *dch, int event, void *data) {
arcofi_fsm(channel_t *dch, int event, void *data) {
isac_chip_t *isac = dch->hw;
if (dch->debug & L1_DEB_MONITOR) {
@ -62,7 +62,7 @@ arcofi_fsm(dchannel_t *dch, int event, void *data) {
}
if (event == ARCOFI_TIMEOUT) {
isac->arcofi_state = ARCOFI_NOP;
test_and_set_bit(FLG_ARCOFI_ERROR, &dch->DFlags);
test_and_set_bit(FLG_ARCOFI_ERROR, &dch->Flags);
wake_up(&isac->arcofi_wait);
return(1);
}
@ -85,7 +85,7 @@ arcofi_fsm(dchannel_t *dch, int event, void *data) {
isac->arcofi_list->next;
send_arcofi(dch);
} else {
if (test_and_clear_bit(FLG_ARCOFI_TIMER, &dch->DFlags)) {
if (test_and_clear_bit(FLG_ARCOFI_TIMER, &dch->Flags)) {
del_timer(&isac->arcofitimer);
}
isac->arcofi_state = ARCOFI_NOP;
@ -109,7 +109,7 @@ arcofi_fsm(dchannel_t *dch, int event, void *data) {
isac->arcofi_state = ARCOFI_TRANSMIT;
send_arcofi(dch);
} else {
if (test_and_clear_bit(FLG_ARCOFI_TIMER, &dch->DFlags)) {
if (test_and_clear_bit(FLG_ARCOFI_TIMER, &dch->Flags)) {
del_timer(&isac->arcofitimer);
}
isac->arcofi_state = ARCOFI_NOP;
@ -125,21 +125,21 @@ arcofi_fsm(dchannel_t *dch, int event, void *data) {
}
static void
arcofi_timer(dchannel_t *dch) {
arcofi_timer(channel_t *dch) {
arcofi_fsm(dch, ARCOFI_TIMEOUT, NULL);
}
void
clear_arcofi(dchannel_t *dch) {
clear_arcofi(channel_t *dch) {
isac_chip_t *isac = dch->hw;
if (test_and_clear_bit(FLG_ARCOFI_TIMER, &dch->DFlags)) {
if (test_and_clear_bit(FLG_ARCOFI_TIMER, &dch->Flags)) {
del_timer(&isac->arcofitimer);
}
}
void
init_arcofi(dchannel_t *dch) {
init_arcofi(channel_t *dch) {
isac_chip_t *isac = dch->hw;
isac->arcofitimer.function = (void *) arcofi_timer;

View File

@ -27,6 +27,6 @@ struct arcofi_msg {
u_char msg[10];
};
extern int arcofi_fsm(dchannel_t *, int, void *);
extern void init_arcofi(dchannel_t *);
extern void clear_arcofi(dchannel_t *);
extern int arcofi_fsm(channel_t *, int, void *);
extern void init_arcofi(channel_t *);
extern void clear_arcofi(channel_t *);

View File

@ -17,8 +17,7 @@
#include <linux/isapnp.h>
#endif
#include <linux/delay.h>
#include "dchannel.h"
#include "bchannel.h"
#include "channel.h"
#include "isac.h"
#include "layer1.h"
#include "debug.h"
@ -144,8 +143,8 @@ typedef struct _fritzpnppci {
spinlock_t lock;
isac_chip_t isac;
hdlc_hw_t hdlc[2];
dchannel_t dch;
bchannel_t bch[2];
channel_t dch;
channel_t bch[2];
u_char ctrlreg;
} fritzpnppci;
@ -235,11 +234,11 @@ fcpci2_write_isac_fifo(void *fc, unsigned char * data, int size)
}
static inline
bchannel_t *Sel_BCS(fritzpnppci *fc, int channel)
channel_t *Sel_BCS(fritzpnppci *fc, int channel)
{
if (fc->bch[0].protocol && (fc->bch[0].channel == channel))
if (test_bit(FLG_ACTIVE, &fc->bch[0].Flags) && (fc->bch[0].channel == channel))
return(&fc->bch[0]);
else if (fc->bch[1].protocol && (fc->bch[1].channel == channel))
else if (test_bit(FLG_ACTIVE, &fc->bch[1].Flags) && (fc->bch[1].channel == channel))
return(&fc->bch[1]);
else
return(NULL);
@ -272,7 +271,7 @@ __write_ctrl_pciv2(fritzpnppci *fc, hdlc_hw_t *hdlc, int channel) {
}
void
write_ctrl(bchannel_t *bch, int which) {
write_ctrl(channel_t *bch, int which) {
fritzpnppci *fc = bch->inst.privat;
hdlc_hw_t *hdlc = bch->hw;
@ -349,47 +348,49 @@ disable_hwirq(fritzpnppci *fc)
}
static int
modehdlc(bchannel_t *bch, int bc, int protocol)
modehdlc(channel_t *bch, int bc, int protocol)
{
hdlc_hw_t *hdlc = bch->hw;
if (bch->debug & L1_DEB_HSCX)
mISDN_debugprint(&bch->inst, "hdlc %c protocol %x-->%x ch %d-->%d",
'A' + bch->channel, bch->protocol, protocol, bch->channel, bc);
'A' + bch->channel, bch->state, protocol, bch->channel, bc);
if ((protocol != -1) && (bc != bch->channel))
printk(KERN_WARNING "%s: fritzcard mismatch channel(%d/%d)\n", __FUNCTION__, bch->channel, bc);
hdlc->ctrl.ctrl = 0;
switch (protocol) {
case (-1): /* used for init */
bch->protocol = -1;
bch->state = -1;
bch->channel = bc;
case (ISDN_PID_NONE):
if (bch->protocol == ISDN_PID_NONE)
if (bch->state == ISDN_PID_NONE)
break;
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
hdlc->ctrl.sr.mode = HDLC_MODE_TRANS;
write_ctrl(bch, 5);
bch->protocol = ISDN_PID_NONE;
bch->state = ISDN_PID_NONE;
test_and_clear_bit(FLG_HDLC, &bch->Flags);
test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags);
break;
case (ISDN_PID_L1_B_64TRANS):
bch->protocol = protocol;
bch->state = protocol;
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
hdlc->ctrl.sr.mode = HDLC_MODE_TRANS;
write_ctrl(bch, 5);
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
write_ctrl(bch, 1);
hdlc->ctrl.sr.cmd = 0;
// FIXME bch_sched_event(bch, B_XMTBUFREADY);
test_and_set_bit(FLG_TRANSPARENT, &bch->Flags);
break;
case (ISDN_PID_L1_B_64HDLC):
bch->protocol = protocol;
bch->state = protocol;
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
hdlc->ctrl.sr.mode = HDLC_MODE_ITF_FLG;
write_ctrl(bch, 5);
hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
write_ctrl(bch, 1);
hdlc->ctrl.sr.cmd = 0;
// FIXME bch_sched_event(bch, B_XMTBUFREADY);
test_and_set_bit(FLG_HDLC, &bch->Flags);
break;
default:
mISDN_debugprint(&bch->inst, "prot not known %x", protocol);
@ -399,7 +400,7 @@ modehdlc(bchannel_t *bch, int bc, int protocol)
}
static void
hdlc_empty_fifo(bchannel_t *bch, int count)
hdlc_empty_fifo(channel_t *bch, int count)
{
register u_int *ptr;
u_char *p;
@ -409,14 +410,20 @@ hdlc_empty_fifo(bchannel_t *bch, int count)
if ((fc->dch.debug & L1_DEB_HSCX) && !(fc->dch.debug & L1_DEB_HSCX_FIFO))
mISDN_debugprint(&bch->inst, "hdlc_empty_fifo %d", count);
if (bch->rx_idx + count > MAX_DATA_MEM) {
if (fc->dch.debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "hdlc_empty_fifo: incoming packet too large");
if (!bch->rx_skb) {
if (!(bch->rx_skb = alloc_stack_skb(bch->maxlen, bch->up_headerlen))) {
printk(KERN_WARNING "mISDN: B receive out of memory\n");
return;
}
}
if ((bch->rx_skb->len + count) > bch->maxlen) {
if (bch->debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "hdlc_empty_fifo overrun %d",
bch->rx_skb->len + count);
return;
}
p = bch->rx_buf + bch->rx_idx;
p = skb_put(bch->rx_skb, count);
ptr = (u_int *)p;
bch->rx_idx += count;
if (fc->type == AVM_FRITZ_PCIV2) {
while (cnt < count) {
#ifdef __powerpc__
@ -452,21 +459,21 @@ hdlc_empty_fifo(bchannel_t *bch, int count)
}
}
if (fc->dch.debug & L1_DEB_HSCX_FIFO) {
char *t = bch->blog;
char *t = bch->log;
if (fc->type == AVM_FRITZ_PNP)
p = (u_char *) ptr;
t += sprintf(t, "hdlc_empty_fifo %c cnt %d",
bch->channel ? 'B' : 'A', count);
mISDN_QuickHex(t, p, count);
mISDN_debugprint(&bch->inst, bch->blog);
mISDN_debugprint(&bch->inst, bch->log);
}
}
#define HDLC_FIFO_SIZE 32
static void
hdlc_fill_fifo(bchannel_t *bch)
hdlc_fill_fifo(channel_t *bch)
{
fritzpnppci *fc = bch->inst.privat;
hdlc_hw_t *hdlc = bch->hw;
@ -476,15 +483,17 @@ hdlc_fill_fifo(bchannel_t *bch)
if ((bch->debug & L1_DEB_HSCX) && !(bch->debug & L1_DEB_HSCX_FIFO))
mISDN_debugprint(&bch->inst, "%s", __FUNCTION__);
count = bch->tx_len - bch->tx_idx;
if (!bch->tx_skb)
return;
count = bch->tx_skb->len - bch->tx_idx;
if (count <= 0)
return;
p = bch->tx_buf + bch->tx_idx;
p = bch->tx_skb->data + bch->tx_idx;
hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XME;
if (count > HDLC_FIFO_SIZE) {
count = HDLC_FIFO_SIZE;
} else {
if (bch->protocol != ISDN_PID_L1_B_64TRANS)
if (test_bit(FLG_HDLC, &bch->Flags))
hdlc->ctrl.sr.cmd |= HDLC_CMD_XME;
}
if ((bch->debug & L1_DEB_HSCX) && !(bch->debug & L1_DEB_HSCX_FIFO))
@ -529,51 +538,49 @@ hdlc_fill_fifo(bchannel_t *bch)
}
}
if (bch->debug & L1_DEB_HSCX_FIFO) {
char *t = bch->blog;
char *t = bch->log;
if (fc->type == AVM_FRITZ_PNP)
p = (u_char *) ptr;
t += sprintf(t, "hdlc_fill_fifo %c cnt %d",
bch->channel ? 'B' : 'A', count);
mISDN_QuickHex(t, p, count);
mISDN_debugprint(&bch->inst, bch->blog);
mISDN_debugprint(&bch->inst, bch->log);
}
}
static void
HDLC_irq_xpr(bchannel_t *bch)
HDLC_irq_xpr(channel_t *bch)
{
if (bch->tx_idx < bch->tx_len)
if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len)
hdlc_fill_fifo(bch);
else {
if (bch->tx_skb)
dev_kfree_skb(bch->tx_skb);
bch->tx_idx = 0;
if (test_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
struct sk_buff *skb = bch->next_skb;
mISDN_head_t *hh;
if (skb) {
if (test_bit(FLG_TX_NEXT, &bch->Flags)) {
bch->tx_skb = bch->next_skb;
if (bch->tx_skb) {
mISDN_head_t *hh = mISDN_HEAD_P(bch->tx_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);
test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
queue_ch_frame(bch, CONFIRM, hh->dinfo, NULL);
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);
test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
}
} else {
bch->tx_len = 0;
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
bch->tx_skb = NULL;
test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
}
}
}
static void
HDLC_irq(bchannel_t *bch, u_int stat)
HDLC_irq(channel_t *bch, u_int stat)
{
int len;
struct sk_buff *skb;
@ -592,42 +599,58 @@ HDLC_irq(bchannel_t *bch, u_int stat)
write_ctrl(bch, 1);
hdlc->ctrl.sr.cmd &= ~HDLC_CMD_RRS;
write_ctrl(bch, 1);
bch->rx_idx = 0;
if (bch->rx_skb)
skb_trim(bch->rx_skb, 0);
} else {
if (!(len = (stat & HDLC_STAT_RML_MASK)>>8))
len = 32;
hdlc_empty_fifo(bch, len);
if ((stat & HDLC_STAT_RME) || (bch->protocol == ISDN_PID_L1_B_64TRANS)) {
if (!bch->rx_skb)
goto handle_tx;
if ((stat & HDLC_STAT_RME) || test_bit(FLG_TRANSPARENT, &bch->Flags)) {
if (((stat & HDLC_STAT_CRCVFRRAB)==HDLC_STAT_CRCVFR) ||
(bch->protocol == ISDN_PID_L1_B_64TRANS)) {
if (!(skb = alloc_stack_skb(bch->rx_idx, bch->up_headerlen)))
printk(KERN_WARNING "HDLC: receive out of memory\n");
else {
memcpy(skb_put(skb, bch->rx_idx),
bch->rx_buf, bch->rx_idx);
queue_bch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
test_bit(FLG_TRANSPARENT, &bch->Flags)) {
if (bch->rx_skb->len < MISDN_COPY_SIZE) {
skb = alloc_stack_skb(bch->rx_skb->len, bch->up_headerlen);
if (skb) {
memcpy(skb_put(skb, bch->rx_skb->len),
bch->rx_skb->data, bch->rx_skb->len);
skb_trim(bch->rx_skb, 0);
} else {
skb = bch->rx_skb;
bch->rx_skb = NULL;
}
} else {
skb = bch->rx_skb;
bch->rx_skb = NULL;
}
bch->rx_idx = 0;
queue_ch_frame(bch, INDICATION, MISDN_ID_ANY, skb);
} else {
if (bch->debug & L1_DEB_HSCX)
mISDN_debugprint(&bch->inst, "invalid frame");
else
mISDN_debugprint(&bch->inst, "ch%d invalid frame %#x", bch->channel, stat);
bch->rx_idx = 0;
skb_trim(bch->rx_skb, 0);
}
}
}
}
handle_tx:
if (stat & HDLC_INT_XDU) {
/* Here we lost an TX interrupt, so
* restart transmitting the whole frame on HDLC
* in transparent mode we send the next data
*/
if (bch->debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "ch%d XDU tx_len(%d) tx_idx(%d) Flag(%lx)",
bch->channel, bch->tx_len, bch->tx_idx, bch->Flag);
if (bch->tx_len) {
if (bch->protocol != ISDN_PID_L1_B_64TRANS)
if (bch->debug & L1_DEB_WARN) {
if (bch->tx_skb)
mISDN_debugprint(&bch->inst, "ch%d XDU tx_len(%d) tx_idx(%d) Flags(%lx)",
bch->channel, bch->tx_skb->len, bch->tx_idx, bch->Flags);
else
mISDN_debugprint(&bch->inst, "ch%d XDU no tx_skb Flags(%lx)",
bch->channel, bch->Flags);
}
if (bch->tx_skb && bch->tx_skb->len) {
if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
bch->tx_idx = 0;
}
hdlc->ctrl.sr.xml = 0;
@ -644,7 +667,7 @@ static inline void
HDLC_irq_main(fritzpnppci *fc)
{
u_int stat;
bchannel_t *bch;
channel_t *bch;
stat = read_status(fc, 0);
if (stat & HDLC_INT_MASK) {
@ -736,47 +759,25 @@ avm_fritzv2_interrupt(int intno, void *dev_id, struct pt_regs *regs)
static int
hdlc_down(mISDNinstance_t *inst, struct sk_buff *skb)
{
bchannel_t *bch;
channel_t *bch;
int ret = 0;
mISDN_head_t *hh;
mISDN_head_t *hh = mISDN_HEAD_P(skb);
u_long flags;
hh = mISDN_HEAD_P(skb);
bch = container_of(inst, bchannel_t, inst);
if ((hh->prim == PH_DATA_REQ) ||
(hh->prim == (DL_DATA | REQUEST))) {
if (skb->len <= 0) {
printk(KERN_WARNING "%s: skb too small\n", __FUNCTION__);
return(-EINVAL);
}
if (skb->len > MAX_DATA_MEM) {
printk(KERN_WARNING "%s: skb too large\n", __FUNCTION__);
return(-EINVAL);
}
bch = container_of(inst, channel_t, inst);
if ((hh->prim == PH_DATA_REQ) || (hh->prim == DL_DATA_REQ)) {
spin_lock_irqsave(inst->hwlock, flags);
if (bch->next_skb) {
mISDN_debugprint(&bch->inst, " l2l1 next_skb exist this shouldn't happen");
spin_unlock_irqrestore(inst->hwlock, flags);
return(-EBUSY);
}
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;
spin_unlock_irqrestore(inst->hwlock, flags);
return(0);
} else {
bch->tx_len = skb->len;
memcpy(bch->tx_buf, skb->data, bch->tx_len);
bch->tx_idx = 0;
ret = channel_senddata(bch, hh->dinfo, skb);
if (ret > 0) { /* direct TX */
hdlc_fill_fifo(bch);
spin_unlock_irqrestore(inst->hwlock, flags);
skb_trim(skb, 0);
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM,
hh->dinfo, skb));
ret = 0;
}
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
spin_unlock_irqrestore(inst->hwlock, flags);
return(ret);
}
if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
(hh->prim == (DL_ESTABLISH | REQUEST))) {
if (!test_and_set_bit(BC_FLG_ACTIV, &bch->Flag)) {
if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) {
spin_lock_irqsave(inst->hwlock, flags);
ret = modehdlc(bch, bch->channel,
bch->inst.pid.protocol[1]);
@ -788,13 +789,18 @@ hdlc_down(mISDNinstance_t *inst, struct sk_buff *skb)
(hh->prim == (DL_RELEASE | REQUEST)) ||
((hh->prim == (PH_CONTROL | REQUEST) && (hh->dinfo == HW_DEACTIVATE)))) {
spin_lock_irqsave(inst->hwlock, flags);
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flags)) {
dev_kfree_skb(bch->next_skb);
bch->next_skb = NULL;
}
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
if (bch->tx_skb) {
dev_kfree_skb(bch->tx_skb);
bch->tx_skb = NULL;
bch->tx_idx = 0;
}
test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
modehdlc(bch, bch->channel, 0);
test_and_clear_bit(BC_FLG_ACTIV, &bch->Flag);
test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
spin_unlock_irqrestore(inst->hwlock, flags);
skb_trim(skb, 0);
if (hh->prim != (PH_CONTROL | REQUEST))
@ -1026,9 +1032,9 @@ release_card(fritzpnppci *card)
free_irq(card->irq, card);
spin_lock_irqsave(&card->lock, flags);
release_region(card->addr, 32);
mISDN_free_bch(&card->bch[1]);
mISDN_free_bch(&card->bch[0]);
mISDN_free_dch(&card->dch);
mISDN_freechannel(&card->bch[1]);
mISDN_freechannel(&card->bch[0]);
mISDN_freechannel(&card->dch);
spin_unlock_irqrestore(&card->lock, flags);
fritz.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
spin_lock_irqsave(&fritz.lock, flags);
@ -1088,9 +1094,9 @@ fritz_manager(void *data, u_int prim, void *arg) {
switch(prim) {
case MGR_REGLAYER | CONFIRM:
if (channel == 2)
dch_set_para(&card->dch, &inst->st->para);
mISDN_setpara(&card->dch, &inst->st->para);
else
bch_set_para(&card->bch[channel], &inst->st->para);
mISDN_setpara(&card->bch[channel], &inst->st->para);
break;
case MGR_UNREGLAYER | REQUEST:
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
@ -1110,9 +1116,9 @@ fritz_manager(void *data, u_int prim, void *arg) {
arg = NULL;
case MGR_ADDSTPARA | INDICATION:
if (channel == 2)
dch_set_para(&card->dch, arg);
mISDN_setpara(&card->dch, arg);
else
bch_set_para(&card->bch[channel], arg);
mISDN_setpara(&card->bch[channel], arg);
break;
case MGR_RELEASE | INDICATION:
if (channel == 2) {
@ -1174,7 +1180,7 @@ static int __devinit setup_instance(fritzpnppci *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);
mISDN_initchannel(&card->dch, MSK_INIT_DCHANNEL, MAX_DFRAME_LEN_L1);
for (i=0; i<2; i++) {
card->bch[i].channel = i;
mISDN_init_instance(&card->bch[i].inst, &fritz, card, hdlc_down);
@ -1183,16 +1189,16 @@ static int __devinit setup_instance(fritzpnppci *card)
card->bch[i].inst.class_dev.dev = dev;
card->bch[i].debug = debug;
sprintf(card->bch[i].inst.name, "%s B%d", card->dch.inst.name, i+1);
mISDN_init_bch(&card->bch[i]);
mISDN_initchannel(&card->bch[i], MSK_INIT_BCHANNEL, MAX_DATA_MEM);
card->bch[i].hw = &card->hdlc[i];
}
printk(KERN_DEBUG "fritz card %p dch %p bch1 %p bch2 %p\n",
card, &card->dch, &card->bch[0], &card->bch[1]);
err = setup_fritz(card);
if (err) {
mISDN_free_dch(&card->dch);
mISDN_free_bch(&card->bch[1]);
mISDN_free_bch(&card->bch[0]);
mISDN_freechannel(&card->dch);
mISDN_freechannel(&card->bch[1]);
mISDN_freechannel(&card->bch[0]);
spin_lock_irqsave(&fritz.lock, flags);
list_del(&card->list);
spin_unlock_irqrestore(&fritz.lock, flags);

View File

@ -1,155 +0,0 @@
/* $Id$
*
* Author Karsten Keil (keil@isdn4linux.de)
*
* This file is (c) under GNU PUBLIC LICENSE
*
*/
#include <linux/module.h>
#include <linux/mISDNif.h>
#include "layer1.h"
#include "bchannel.h"
#include "helper.h"
#ifdef OBSOLETE
static void
bchannel_bh(bchannel_t *bch)
{
struct sk_buff *skb;
u_int pr;
int ret;
mISDN_head_t *hh;
if (!bch)
return;
#if 0
printk(KERN_DEBUG "%s: event %x\n", __FUNCTION__, bch->event);
if (bch->dev)
printk(KERN_DEBUG "%s: rpflg(%x) wpflg(%x)\n", __FUNCTION__,
bch->dev->rport.Flag, bch->dev->wport.Flag);
#endif
if (test_and_clear_bit(B_XMTBUFREADY, &bch->event)) {
skb = bch->next_skb;
if (skb) {
hh = mISDN_HEAD_P(skb);
bch->next_skb = NULL;
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
pr = DL_DATA | CONFIRM;
else
pr = PH_DATA | CONFIRM;
#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
if (mISDN_queueup_newhead(&bch->inst, 0, pr, hh->dinfo, skb))
dev_kfree_skb(skb);
}
}
if (test_and_clear_bit(B_RCVBUFREADY, &bch->event)) {
#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
while ((skb = skb_dequeue(&bch->rqueue))) {
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
pr = DL_DATA | INDICATION;
else
pr = PH_DATA | INDICATION;
ret = mISDN_queueup_newhead(&bch->inst, 0, pr, MISDN_ID_ANY, skb);
if (ret < 0) {
printk(KERN_WARNING "%s: deliver err %d\n",
__FUNCTION__, ret);
dev_kfree_skb(skb);
}
}
}
if (bch->hw_bh)
bch->hw_bh(bch);
}
#endif
int
mISDN_init_bch(bchannel_t *bch) {
int devtyp = mISDN_RAW_DEVICE;
if (!(bch->blog = kmalloc(MAX_BLOG_SPACE, GFP_ATOMIC))) {
printk(KERN_WARNING
"mISDN: No memory for blog\n");
return(-ENOMEM);
}
if (!(bch->rx_buf = kmalloc(MAX_DATA_MEM, GFP_ATOMIC))) {
printk(KERN_WARNING
"mISDN: No memory for bchannel rx_buf\n");
kfree(bch->blog);
bch->blog = NULL;
return (-ENOMEM);
}
if (!(bch->tx_buf = kmalloc(MAX_DATA_MEM, GFP_ATOMIC))) {
printk(KERN_WARNING
"mISDN: No memory for bchannel tx_buf\n");
kfree(bch->blog);
bch->blog = NULL;
kfree(bch->rx_buf);
bch->rx_buf = NULL;
return (-ENOMEM);
}
#ifdef OBSOLETE
skb_queue_head_init(&bch->rqueue);
bch->event = 0;
INIT_WORK(&bch->work, (void *)(void *)bchannel_bh, bch);
#endif
bch->next_skb = NULL;
bch->Flag = 0;
bch->rx_idx = 0;
bch->tx_len = 0;
bch->tx_idx = 0;
bch->hw_bh = NULL;
if (!bch->dev) {
if (bch->inst.obj->ctrl(&bch->dev, MGR_GETDEVICE | REQUEST,
&devtyp)) {
printk(KERN_WARNING
"mISDN: no raw device for bchannel\n");
}
}
return(0);
}
int
mISDN_free_bch(bchannel_t *bch) {
#ifdef OBSOLETE
#ifdef HAS_WORKQUEUE
if (bch->work.pending)
printk(KERN_ERR "mISDN_free_bch work:(%lx)\n", bch->work.pending);
#else
if (bch->work.sync)
printk(KERN_ERR "mISDN_free_bch work:(%lx)\n", bch->work.sync);
#endif
discard_queue(&bch->rqueue);
#endif
kfree(bch->blog);
bch->blog = NULL;
kfree(bch->rx_buf);
bch->rx_buf = NULL;
kfree(bch->tx_buf);
bch->tx_buf = NULL;
if (bch->next_skb) {
dev_kfree_skb(bch->next_skb);
bch->next_skb = NULL;
}
if (bch->inst.obj->ctrl(bch->dev, MGR_DELDEVICE | REQUEST, NULL)) {
printk(KERN_WARNING
"mISDN: del raw device error\n");
} else
bch->dev = NULL;
return(0);
}
EXPORT_SYMBOL(mISDN_init_bch);
EXPORT_SYMBOL(mISDN_free_bch);

View File

@ -1,120 +0,0 @@
/* $Id$
*
* Basic declarations, defines for Bchannel hardware
*
* 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>
#else
#include <linux/tqueue.h>
#endif
#include <linux/smp.h>
#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <asm/io.h>
#include <linux/ioport.h>
#include <linux/skbuff.h>
#ifdef MISDN_MEMDEBUG
#include "memdbg.h"
#endif
#include "helper.h"
#define MAX_BLOG_SPACE 256
#define BC_FLG_INIT 1
#define BC_FLG_ACTIV 2
#define BC_FLG_TX_BUSY 3
#define BC_FLG_NOFRAME 4
#define BC_FLG_HALF 5
#define BC_FLG_EMPTY 6
#define BC_FLG_ORIG 7
#define BC_FLG_DLEETX 8
#define BC_FLG_LASTDLE 9
#define BC_FLG_FIRST 10
#define BC_FLG_LASTDATA 11
#define BC_FLG_NMD_DATA 12
#define BC_FLG_FTI_RUN 13
#define BC_FLG_LL_OK 14
#define BC_FLG_LL_CONN 15
#define BC_FLG_TX_NEXT 16
#define BC_FLG_DTMFSEND 17
typedef struct _bchannel_t {
int channel;
int protocol;
u_long Flag;
int debug;
mISDNinstance_t inst;
mISDNdevice_t *dev;
void *hw;
u_char (*Read_Reg)(void *, int, u_char);
void (*Write_Reg)(void *, int, u_char, u_char);
struct sk_buff *next_skb;
u_char *tx_buf;
int tx_idx;
int tx_len;
u_char *rx_buf;
int rx_idx;
u_char *blog;
u_char *conmsg;
struct timer_list transbusy;
#ifdef OBSOLETE
struct sk_buff_head rqueue; /* B-Channel receive Queue */
struct work_struct work;
u_long event;
#endif
void (*hw_bh) (struct _bchannel_t *);
int maxdatasize;
int up_headerlen;
int err_crc;
int err_tx;
int err_rdo;
int err_inv;
} bchannel_t;
extern int mISDN_init_bch(bchannel_t *);
extern int mISDN_free_bch(bchannel_t *);
static inline void
bch_set_para(bchannel_t *bch, mISDN_stPara_t *stp)
{
if (stp) {
bch->maxdatasize = stp->maxdatalen;
bch->up_headerlen = stp->up_headerlen;
} else {
bch->maxdatasize = 0;
bch->up_headerlen = 0;
}
}
static inline void
queue_bch_frame(bchannel_t *bch, u_int pr, int dinfo, struct sk_buff *skb)
{
int err;
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
pr |= DL_DATA;
else
pr |= PH_DATA;
err = mISDN_queueup_newhead(&bch->inst, 0, pr, dinfo, skb);
if (unlikely(err)) {
int_errtxt("err=%d", err);
dev_kfree_skb(skb);
}
}
#ifdef OBSOLETE
static inline void
bch_sched_event(bchannel_t *bch, int event)
{
test_and_set_bit(event, &bch->event);
schedule_work(&bch->work);
}
#endif
#endif

View File

@ -0,0 +1,87 @@
/* $Id$
*
* Author (c) Karsten Keil <kkeil@suse.de>
*
* This file is released under the GPLv2
*
*/
#include <linux/module.h>
#include "channel.h"
#include "layer1.h"
int
mISDN_initchannel(channel_t *ch, ulong prop, int maxlen)
{
if (!(ch->log = kmalloc(MAX_LOG_SPACE, GFP_ATOMIC))) {
printk(KERN_WARNING
"mISDN: No memory for channel log\n");
return(-ENOMEM);
}
ch->Flags = prop;
ch->maxlen = maxlen;
ch->hw = NULL;
ch->rx_skb = NULL;
ch->tx_skb = NULL;
ch->tx_idx = 0;
ch->next_skb = NULL;
return(0);
}
int
mISDN_freechannel(channel_t *ch)
{
if (ch->tx_skb) {
dev_kfree_skb(ch->tx_skb);
ch->tx_skb = NULL;
}
if (ch->rx_skb) {
dev_kfree_skb(ch->rx_skb);
ch->rx_skb = NULL;
}
if (ch->next_skb) {
dev_kfree_skb(ch->next_skb);
ch->next_skb = NULL;
}
kfree(ch->log);
ch->log = NULL;
return(0);
}
/* need called with HW lock */
int
mISDN_setpara(channel_t *ch, mISDN_stPara_t *stp)
{
if (!stp) { // clear parameters
ch->maxlen = 0;
ch->up_headerlen = 0;
return(0);
}
if (stp->up_headerlen)
ch->up_headerlen = stp->up_headerlen;
if (stp->maxdatalen) {
if (ch->maxlen < stp->maxdatalen) {
if (ch->rx_skb) {
struct sk_buff *skb;
skb = alloc_skb(stp->maxdatalen +
ch->up_headerlen, GFP_ATOMIC);
if (!skb) {
int_errtxt("no skb for %d+%d", stp->maxdatalen, ch->up_headerlen);
return(-ENOMEM);
}
skb_reserve(skb, ch->up_headerlen);
memcpy(skb_put(skb, ch->rx_skb->len),
ch->rx_skb->data, ch->rx_skb->len);
dev_kfree_skb(ch->rx_skb);
ch->rx_skb = skb;
}
}
ch->maxlen = stp->maxdatalen;
}
return(0);
}
EXPORT_SYMBOL(mISDN_initchannel);
EXPORT_SYMBOL(mISDN_freechannel);
EXPORT_SYMBOL(mISDN_setpara);

View File

@ -0,0 +1,148 @@
/* $Id$
*
* Basic declarations for a mISDN HW channel
*
* Author (c) Karsten Keil <kkeil@suse.de>
*
* This file is released under the GPLv2
*
*/
#ifndef MISDN_CHANNEL_H
#define MISDN_CHANNEL_H
#include <linux/mISDNif.h>
#include <linux/timer.h>
#include <linux/skbuff.h>
#include "helper.h"
#ifdef MISDN_MEMDEBUG
#include "memdbg.h"
#endif
#define MAX_DFRAME_LEN_L1 300
#define MAX_MON_FRAME 32
#define MAX_LOG_SPACE 2048
#define MISDN_COPY_SIZE 32
/* channel->Flags bit field */
#define FLG_TX_BUSY 0 // tx_buf in use
#define FLG_TX_NEXT 1 // next_skb in use
#define FLG_L1_BUSY 2 // L1 is permanent busy
#define FLG_USED 5 // channel is in use
#define FLG_ACTIVE 6 // channel is activated
#define FLG_BUSY_TIMER 7
/* channel type */
#define FLG_DCHANNEL 8 // channel is D-channel
#define FLG_BCHANNEL 9 // channel is B-channel
#define FLG_ECHANNEL 10 // channel is E-channel
#define FLG_TRANSPARENT 12 // channel use transparent data
#define FLG_HDLC 13 // channel use hdlc data
#define FLG_L2DATA 14 // channel use L2 DATA primitivs
#define FLG_ORIGIN 15 // channel is on origin site
/* channel specific stuff */
/* arcofi specific */
#define FLG_ARCOFI_TIMER 16
#define FLG_ARCOFI_ERROR 17
/* isar specific */
#define FLG_INITIALIZED 16
#define FLG_DLEETX 17
#define FLG_LASTDLE 18
#define FLG_FIRST 19
#define FLG_LASTDATA 20
#define FLG_NMD_DATA 21
#define FLG_FTI_RUN 22
#define FLG_LL_OK 23
#define FLG_LL_CONN 24
#define FLG_DTMFSEND 25
#define MSK_INIT_DCHANNEL ((1<<FLG_DCHANNEL)|(1<<FLG_HDLC))
#define MSK_INIT_BCHANNEL (1<<FLG_BCHANNEL)
#define MSK_INIT_ECHANNEL (1<<FLG_ECHANNEL)
typedef struct _channel_t {
mISDNinstance_t inst;
int channel;
/* basic properties */
u_long Flags;
u_int type;
u_int state;
/* HW access */
u_char (*read_reg) (void *, u_char);
void (*write_reg) (void *, u_char, u_char);
void (*read_fifo) (void *, u_char *, int);
void (*write_fifo) (void *, u_char *, int);
void *hw;
struct timer_list timer;
/* receive data */
struct sk_buff *rx_skb;
int maxlen;
int up_headerlen;
/* send data */
struct sk_buff *next_skb;
struct sk_buff *tx_skb;
int tx_idx;
/* debug */
int debug;
char *log;
/* statistics */
int err_crc;
int err_tx;
int err_rx;
} channel_t;
extern int mISDN_initchannel(channel_t *, ulong, int);
extern int mISDN_freechannel(channel_t *);
extern int mISDN_setpara(channel_t *, mISDN_stPara_t *);
static inline void
queue_ch_frame(channel_t *ch, u_int pr, int dinfo, struct sk_buff *skb)
{
int err;
pr |= test_bit(FLG_L2DATA, &ch->Flags) ? DL_DATA : PH_DATA;
if (!skb)
err = mISDN_queue_data(&ch->inst, FLG_MSG_UP, pr, dinfo, 0, NULL, ch->up_headerlen);
else
err = mISDN_queueup_newhead(&ch->inst, 0, pr, dinfo, skb);
if (unlikely(err)) {
int_errtxt("err=%d", err);
if (skb)
dev_kfree_skb(skb);
}
}
static inline int
channel_senddata(channel_t *ch, int di, struct sk_buff *skb)
{
/* HW lock must be obtained */
/* check oversize */
if (skb->len <= 0) {
printk(KERN_WARNING "%s: skb too small\n", __FUNCTION__);
return(-EINVAL);
}
if (skb->len > ch->maxlen) {
printk(KERN_WARNING "%s: skb too large(%d/%d)\n",
__FUNCTION__, skb->len, ch->maxlen);
return(-EINVAL);
}
/* check for pending next_skb */
if (ch->next_skb) {
printk(KERN_WARNING "%s: next_skb exist ERROR (skb->len=%d next_skb->len=%d)\n",
__FUNCTION__, skb->len, ch->next_skb->len);
return(-EBUSY);
}
if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) {
test_and_set_bit(FLG_TX_NEXT, &ch->Flags);
ch->next_skb = skb;
return(0);
} else {
/* write to fifo */
ch->tx_skb = skb;
ch->tx_idx = 0;
queue_ch_frame(ch, CONFIRM, di, NULL);
return(skb->len);
}
}
#endif

View File

@ -1,118 +0,0 @@
/* $Id$
*
* Author Karsten Keil (keil@isdn4linux.de)
*
* This file is (c) under GNU PUBLIC LICENSE
*
*/
#include <linux/module.h>
#include <linux/mISDNif.h>
#include "layer1.h"
#include "helper.h"
#include "dchannel.h"
#ifdef OBSOLETE
static void
dchannel_bh(dchannel_t *dch)
{
struct sk_buff *skb;
int err;
mISDN_head_t *hh;
if (!dch)
return;
if (dch->debug)
printk(KERN_DEBUG "%s: event %lx\n", __FUNCTION__, dch->event);
#if 0
if (test_and_clear_bit(D_CLEARBUSY, &dch->event)) {
if (dch->debug)
mISDN_debugprint(&dch->inst, "D-Channel Busy cleared");
stptr = dch->stlist;
while (stptr != NULL) {
stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL);
stptr = stptr->next;
}
}
#endif
if (test_and_clear_bit(D_XMTBUFREADY, &dch->event)) {
if ((skb = dch->next_skb)) {
hh = mISDN_HEAD_P(skb);
dch->next_skb = NULL;
skb_trim(skb, 0);
if (mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_CNF, hh->dinfo, skb))
dev_kfree_skb(skb);
}
}
if (test_and_clear_bit(D_RCVBUFREADY, &dch->event)) {
while ((skb = skb_dequeue(&dch->rqueue))) {
err = mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_IND, MISDN_ID_ANY, skb);
if (err < 0) {
printk(KERN_WARNING "%s: deliver err %d\n", __FUNCTION__, err);
dev_kfree_skb(skb);
}
}
}
if (dch->hw_bh)
dch->hw_bh(dch);
}
#endif
int
mISDN_init_dch(dchannel_t *dch) {
if (!(dch->dlog = kmalloc(MAX_DLOG_SPACE, GFP_ATOMIC))) {
printk(KERN_WARNING
"mISDN: No memory for dlog\n");
return(-ENOMEM);
}
if (!(dch->tx_buf = kmalloc(MAX_DFRAME_LEN_L1, GFP_ATOMIC))) {
printk(KERN_WARNING
"mISDN: No memory for dchannel tx_buf\n");
kfree(dch->dlog);
dch->dlog = NULL;
return(-ENOMEM);
}
dch->hw = NULL;
dch->rx_skb = NULL;
dch->tx_idx = 0;
dch->next_skb = NULL;
#ifdef OBSOLETE
dch->event = 0;
INIT_WORK(&dch->work, (void *)(void *)dchannel_bh, dch);
dch->hw_bh = NULL;
skb_queue_head_init(&dch->rqueue);
#endif
return(0);
}
int
mISDN_free_dch(dchannel_t *dch) {
#ifdef OBSOLETE
#ifdef HAS_WORKQUEUE
if (dch->work.pending)
printk(KERN_ERR "mISDN_free_dch work:(%lx)\n", dch->work.pending);
#else
if (dch->work.sync)
printk(KERN_ERR "mISDN_free_dch work:(%lx)\n", dch->work.sync);
#endif
discard_queue(&dch->rqueue);
#endif
if (dch->rx_skb) {
dev_kfree_skb(dch->rx_skb);
dch->rx_skb = NULL;
}
kfree(dch->tx_buf);
dch->tx_buf = NULL;
if (dch->next_skb) {
dev_kfree_skb(dch->next_skb);
dch->next_skb = NULL;
}
kfree(dch->dlog);
dch->dlog = NULL;
return(0);
}
EXPORT_SYMBOL(mISDN_init_dch);
EXPORT_SYMBOL(mISDN_free_dch);

View File

@ -1,96 +0,0 @@
/* $Id$
*
* Basic declarations for dchannel HW
*
* This file is (c) under GNU PUBLIC LICENSE
*
*/
#include <linux/mISDNif.h>
#ifdef HAS_WORKQUEUE
#include <linux/workqueue.h>
#else
#include <linux/tqueue.h>
#endif
#include <linux/smp.h>
#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <asm/io.h>
#include <linux/ioport.h>
#include <linux/skbuff.h>
#ifdef MISDN_MEMDEBUG
#include "memdbg.h"
#endif
#define MAX_DFRAME_LEN_L1 300
#define MAX_MON_FRAME 32
#define MAX_DLOG_SPACE 2048
#define FLG_TWO_DCHAN 4
#define FLG_TX_BUSY 5
#define FLG_TX_NEXT 6
#define FLG_L1_DBUSY 7
#define FLG_DBUSY_TIMER 8
#define FLG_LOCK_ATOMIC 9
#define FLG_ARCOFI_TIMER 10
#define FLG_ARCOFI_ERROR 11
#define FLG_HW_L1_UINT 12
#define FLG_HW_INIT 13
typedef struct _dchannel_t {
int channel;
mISDNinstance_t inst;
u_long DFlags;
u_int type;
u_int ph_state;
u_char l1_up;
u_char (*read_reg) (void *, u_char);
void (*write_reg) (void *, u_char, u_char);
void (*read_fifo) (void *, u_char *, int);
void (*write_fifo) (void *, u_char *, int);
char *dlog;
int debug;
struct sk_buff *rx_skb;
struct sk_buff *next_skb;
u_char *tx_buf;
int tx_idx;
int tx_len;
int up_headerlen;
int err_crc;
int err_tx;
int err_rx;
void *hw;
struct timer_list dbusytimer;
#ifdef OBSOLETE
u_long event;
struct sk_buff_head rqueue; /* D-channel receive queue */
struct work_struct work;
#endif
void (*hw_bh) (struct _dchannel_t *);
} dchannel_t;
#define MON0_RX 1
#define MON1_RX 2
#define MON0_TX 4
#define MON1_TX 8
extern int mISDN_init_dch(dchannel_t *);
extern int mISDN_free_dch(dchannel_t *);
static inline void
dch_set_para(dchannel_t *dch, mISDN_stPara_t *stp)
{
if (stp)
dch->up_headerlen = stp->up_headerlen;
else
dch->up_headerlen = 0;
}
#ifdef OBSOLETE
static inline void
dchannel_sched_event(dchannel_t *dch, int event)
{
test_and_set_bit(event, &dch->event);
schedule_work(&dch->work);
}
#endif

View File

@ -176,14 +176,6 @@ mISDN_sethead(u_int prim, int dinfo, struct sk_buff *skb)
hh->dinfo = dinfo;
}
static inline int mISDN_send_message(void) {return 0;};
static inline int mISDN_send_data(void) {return 0;};
static inline int mISDN_sendup(void) {return 0;};
static inline int mISDN_sendup_newhead(void) {return 0;};
static inline int mISDN_senddown(void) {return 0;};
static inline int mISDN_senddown_newhead(void) {return 0;};
#define mISDN_queue_up(i, a, s) mISDN_queue_message(i, a | FLG_MSG_UP, s)
#define mISDN_queue_down(i, a, s) mISDN_queue_message(i, a | FLG_MSG_DOWN, s)

File diff suppressed because it is too large Load Diff

View File

@ -35,27 +35,22 @@ typedef unsigned long DWORD;
also registers are assigned differen for HFC-4s/8s and HFC-E1
*/
#define MAX_FRAME_SIZE 2048
// #define MAX_FRAME_SIZE 2048
struct hfc_chan {
/* dch or bch is set, otherwhise this channel is not used */
dchannel_t *dch; /* link if channel is a D-channel */
bchannel_t *bch; /* link if channel is a B-channel */
int rx_idx; /* for D-channel */
BYTE *rx_buf; /* for D-channel */
int port; /* the interface port this channel is associated with */
int nt_mode;
channel_t *ch; /* link if channel is a D-channel */
int port; /* the interface port this channel is associated with */
int nt_timer; /* -1 if off, 0 if elapsed, >0 if running */
int los, ais, slip_tx, slip_rx; /* current alarms */
int jitter;
u_long cfg; /* port configuration */
int sync; /* sync state (used by E1) */
DWORD protocol; /* current protocol */
u_long cfg; /* port configuration */
int sync; /* sync state (used by E1) */
DWORD protocol;/* current protocol */
int slot_tx; /* current pcm slot */
int bank_tx; /* current pcm bank */
int slot_rx;
int bank_rx;
int conf; /* conference setting of TX slot */
int conf; /* conference setting of TX slot */
int txpending; /* if there is currently data in the FIFO 0=no, 1=yes, 2=splloop */
int e1_state; /* keep track of last state */
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -24,8 +24,7 @@
#ifndef __HFCMINI_H__
#define __HFCMINI_H__
#include "dchannel.h"
#include "bchannel.h"
#include "channel.h"
#include "hfcsmcc.h"
@ -105,17 +104,6 @@ typedef struct {
char *device_name;
} hfcsmini_param;
/* channel struct for each fifo */
typedef struct {
bchannel_t *bch;
dchannel_t *dch;
int rx_idx; /* for D-channel */
__u8 *rx_buf; /* for D-channel */
} hfcmini_chan_t;
struct _hfcmini_hw;
/**********************/
@ -143,7 +131,7 @@ typedef struct _hfcmini_hw {
int max_fifo; /* always 4 fifos per port */
__u8 max_z; /* fifo depth -1 */
hfcmini_chan_t chan[MAX_CHAN]; /* line interfaces */
channel_t chan[MAX_CHAN]; /* line interfaces */
__u8 fifomask;

View File

@ -32,7 +32,7 @@
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/usb.h>
#include "dchannel.h"
#include "channel.h"
#include "bchannel.h"
#include "layer1.h"
#include "debug.h"
@ -105,7 +105,7 @@ typedef struct usb_fifo {
typedef struct _hfcsusb_t {
struct list_head list;
spinlock_t lock;
dchannel_t dch;
channel_t dch;
bchannel_t bch[2];
struct usb_device *dev; /* our device */
@ -404,7 +404,7 @@ hfcsusb_manager(void *data, u_int prim, void *arg)
switch (prim) {
case MGR_REGLAYER | CONFIRM:
if (channel == 2)
dch_set_para(&card->dch, &inst->st->para);
mISDN_setpara(&card->dch, &inst->st->para);
else
bch_set_para(&card->bch[channel],
&inst->st->para);
@ -427,7 +427,7 @@ hfcsusb_manager(void *data, u_int prim, void *arg)
arg = NULL;
case MGR_ADDSTPARA | INDICATION:
if (channel == 2)
dch_set_para(&card->dch, arg);
mISDN_setpara(&card->dch, arg);
else
bch_set_para(&card->bch[channel], arg);
break;
@ -480,7 +480,7 @@ hfcsusb_manager(void *data, u_int prim, void *arg)
/* S0 state change event handler */
/*********************************/
static void
S0_new_state(dchannel_t * dch)
S0_new_state(channel_t * dch)
{
u_int prim = PH_SIGNAL | INDICATION;
u_int para = 0;
@ -490,9 +490,9 @@ S0_new_state(dchannel_t * dch)
if (dch->debug)
mISDN_debugprint(&card->dch.inst,
"%s: TE %d",
__FUNCTION__, dch->ph_state);
__FUNCTION__, dch->state);
switch (dch->ph_state) {
switch (dch->state) {
case (0):
prim = PH_CONTROL | INDICATION;
para = HW_RESET;
@ -520,9 +520,9 @@ S0_new_state(dchannel_t * dch)
if (dch->debug)
mISDN_debugprint(&card->dch.inst,
"%s: NT %d",
__FUNCTION__, dch->ph_state);
__FUNCTION__, dch->state);
switch (dch->ph_state) {
switch (dch->state) {
case (1):
dch->l1_up = 0;
card->nt_timer = 0;
@ -573,11 +573,11 @@ S0_new_state(dchannel_t * dch)
static void
state_handler(hfcsusb_t * card, __u8 new_l1_state)
{
if (new_l1_state == card->dch.ph_state
if (new_l1_state == card->dch.state
|| new_l1_state < 1 || new_l1_state > 8)
return;
card->dch.ph_state = new_l1_state;
card->dch.state = new_l1_state;
S0_new_state(&card->dch);
}
@ -720,19 +720,19 @@ hfcsusb_ph_command(hfcsusb_t * card, u_char command)
case S0_L1CMD_AR8:
mISDN_debugprint(&card->dch.inst,
"S0_L1CMD_AR8 at ph_sate = %i",
&card->dch.ph_state);
&card->dch.state);
break;
case S0_L1CMD_AR10:
mISDN_debugprint(&card->dch.inst,
"S0_L1CMD_AR10 at ph_sate = %i",
&card->dch.ph_state);
&card->dch.state);
break;
case S0_L1CMD_ECK:
mISDN_debugprint(&card->dch.inst,
"S0_L1CMD_ECK at ph_sate = %i",
&card->dch.ph_state);
&card->dch.state);
break;
}
}
@ -743,7 +743,7 @@ hfcsusb_ph_command(hfcsusb_t * card, u_char command)
static int
hfcsusb_l1hwD(mISDNinstance_t *inst, struct sk_buff *skb)
{
dchannel_t *dch = container_of(inst, dchannel_t, inst);
channel_t *dch = container_of(inst, channel_t, inst);
int ret = 0;
mISDN_head_t *hh = mISDN_HEAD_P(skb);
hfcsusb_t *card = inst->privat;
@ -767,22 +767,18 @@ hfcsusb_l1hwD(mISDNinstance_t *inst, struct sk_buff *skb)
spin_unlock_irqrestore(inst->hwlock, flags);
return (-EBUSY);
}
if (test_and_set_bit(FLG_TX_BUSY, &dch->DFlags)) {
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
if (test_and_set_bit(FLG_TX_BUSY, &dch->Flags)) {
test_and_set_bit(FLG_TX_NEXT, &dch->Flags);
dch->next_skb = skb;
spin_unlock_irqrestore(inst->hwlock, flags);
return (0);
} else {
/* prepare buffer, which is transmitted by
tx_iso completions later */
dch->tx_len = skb->len;
memcpy(dch->tx_buf, skb->data, dch->tx_len);
dch->tx_skb = skb;
dch->tx_idx = 0;
spin_unlock_irqrestore(inst->hwlock, flags);
skb_trim(skb, 0);
return(mISDN_queueup_newhead(inst, 0, PH_DATA_CNF,
hh->dinfo, skb));
queue_ch_frame(dch, CONFIRM, hh->dinfo, NULL);
}
spin_unlock_irqrestore(inst->hwlock, flags);
return (0);
} else if (hh->prim == (PH_SIGNAL | REQUEST)) {
spin_lock_irqsave(inst->hwlock, flags);
if (hh->dinfo == INFO3_P8)
@ -796,7 +792,7 @@ hfcsusb_l1hwD(mISDNinstance_t *inst, struct sk_buff *skb)
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
spin_lock_irqsave(inst->hwlock, flags);
if (hh->dinfo == HW_RESET) {
if (dch->ph_state != 0)
if (dch->state != 0)
hfcsusb_ph_command(dch->hw,
HFC_L1_ACTIVATE_TE);
hfcsusb_ph_command(dch->hw, S0_L1CMD_ECK);
@ -807,10 +803,10 @@ hfcsusb_l1hwD(mISDNinstance_t *inst, struct sk_buff *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);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
#ifdef FIXME
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->Flags))
dchannel_sched_event(dch, D_CLEARBUSY);
#endif
} else if ((hh->dinfo & HW_TESTLOOP) == HW_TESTLOOP) {
@ -1285,27 +1281,28 @@ rx_int_complete(struct urb *urb, struct pt_regs *regs)
void
next_d_tx_frame(hfcsusb_t * card)
{
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);
if(card->dch.tx_skb)
dev_kfree_skb(card->dch.tx_skb);
if (test_bit(FLG_TX_NEXT, &card->dch.Flags)) {
card->dch.tx_skb = card->dch.next_skb;
if (card->dch.tx_skb) {
mISDN_head_t *hh = mISDN_HEAD_P(card->dch.tx_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);
test_and_clear_bit(FLG_TX_NEXT, &card->dch.Flags);
card->dch.tx_idx = 0;
skb_trim(skb, 0);
if (mISDN_queueup_newhead(&card->dch.inst, 0, PH_DATA_CNF, hh->dinfo, skb))
dev_kfree_skb(skb);
queue_ch_frame(&card->dch, CONFIRM, hh->dinfo, NULL);
} else {
printk(KERN_WARNING
"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_NEXT, &card->dch.Flags);
test_and_clear_bit(FLG_TX_BUSY, &card->dch.Flags);
}
} else
test_and_clear_bit(FLG_TX_BUSY, &card->dch.DFlags);
} else {
card->dch.tx_skb = NULL;
test_and_clear_bit(FLG_TX_BUSY, &card->dch.Flags);
}
}
void
@ -1342,7 +1339,7 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
hfcsusb_t *card = fifo->card;
int k, tx_offset, num_isoc_packets, sink, len, current_len,
errcode;
int *tx_len, *tx_idx;
int tx_len, *tx_idx;
u_char *tx_buf;
int frame_complete, transp_mode=0, fifon, status;
__u8 threshbit;
@ -1374,14 +1371,19 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
switch (fifon) {
case HFCUSB_D_TX:
tx_buf = card->dch.tx_buf;
tx_len = &card->dch.tx_len;
if (!card->dch.tx_skb) {
tx_buf = NULL;
tx_len = 0;
} else {
tx_buf = card->dch.tx_skb->data;
tx_len = card->dch.tx_skb->len;
}
tx_idx = &card->dch.tx_idx;
break;
case HFCUSB_B1_TX:
case HFCUSB_B2_TX:
tx_buf = card->bch[fifo->bch_idx].tx_buf;
tx_len = &card->bch[fifo->bch_idx].tx_len;
tx_len = card->bch[fifo->bch_idx].tx_len;
tx_idx = &card->bch[fifo->bch_idx].tx_idx;
transp_mode = card->bch[fifo->bch_idx].protocol == ISDN_PID_L1_B_64TRANS;
break;
@ -1394,17 +1396,15 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
/* Generate next Iso Packets */
for (k = 0; k < num_isoc_packets; ++k) {
len = (*tx_len - *tx_idx);
if (len) {
len = (tx_len - *tx_idx);
if (len>0) {
/* we lower data margin every msec */
fifo->bit_line -= sink;
current_len = (0 - fifo->bit_line) / 8;
/* maximum 15 byte for every ISO packet makes our life easier */
if (current_len > 14)
current_len = 14;
current_len =
(len <=
current_len) ? len : current_len;
current_len = (len <= current_len) ? len : current_len;
/* how much bit do we put on the line? */
fifo->bit_line += current_len * 8;
@ -1413,8 +1413,7 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
if (current_len == len) {
if (!transp_mode) {
/* here frame completion */
context_iso_urb->
buffer[tx_offset] = 1;
context_iso_urb->buffer[tx_offset] = 1;
/* add 2 byte flags and 16bit CRC at end of ISDN frame */
fifo->bit_line += 32;
}
@ -1422,20 +1421,18 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
}
/* copy tx data to iso-urb buffer */
memcpy(context_iso_urb->buffer +
tx_offset + 1,
memcpy(context_iso_urb->buffer + tx_offset + 1,
(tx_buf + *tx_idx), current_len);
*tx_idx += current_len;
/* define packet delimeters within the URB buffer */
urb->iso_frame_desc[k].offset = tx_offset;
urb->iso_frame_desc[k].length =
current_len + 1;
current_len + 1;
tx_offset += (current_len + 1);
} else {
urb->iso_frame_desc[k].offset =
tx_offset++;
urb->iso_frame_desc[k].offset = tx_offset++;
urb->iso_frame_desc[k].length = 1;
fifo->bit_line -= sink; /* we lower data margin every msec */
@ -1452,14 +1449,17 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
switch (fifon) {
case HFCUSB_D_TX:
next_d_tx_frame(card);
if (fifo->skbuff
&& fifo->delete_flg) {
dev_kfree_skb_any
(fifo->skbuff);
fifo->skbuff =
NULL;
fifo->delete_flg =
0;
if (card->dch.tx_skb) {
tx_len = card->dch.tx_skb->len;
tx_buf = card->dch.tx_skb->data;
} else {
tx_len = 0;
tx_buf = NULL;
}
if (fifo->skbuff && fifo->delete_flg) {
dev_kfree_skb_any(fifo->skbuff);
fifo->skbuff = NULL;
fifo->delete_flg = 0;
}
frame_complete = 0;
break;
@ -1468,15 +1468,12 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
case HFCUSB_B2_TX:
next_b_tx_frame(card, fifo->bch_idx);
card->bch[fifo->bch_idx].tx_len =
0;
test_and_clear_bit
(BC_FLG_TX_BUSY,
&card->bch[fifo->bch_idx].
Flag);
card->bch[fifo->bch_idx].tx_len = 0;
tx_len = 0;
test_and_clear_bit(BC_FLG_TX_BUSY,
&card->bch[fifo->bch_idx].Flag);
card->bch[fifo->bch_idx].tx_idx =
card->bch[fifo->bch_idx].
tx_len;
card->bch[fifo->bch_idx].tx_len;
break;
}
}
@ -1633,13 +1630,10 @@ start_int_fifo(usb_fifo * fifo)
void
hw_init(hfcsusb_t * card)
{
/* setup basic function pointers */
card->dch.hw_bh = S0_new_state;
/* init bchannel mode */
mode_bchannel(&card->bch[0], 0, -1);
mode_bchannel(&card->bch[1], 1, -1);
card->dch.ph_state = 0;
card->dch.state = 0;
}
/* Hardware Initialization */
@ -1797,7 +1791,7 @@ release_card(hfcsusb_t * card)
mode_bchannel(&card->bch[1], 1, ISDN_PID_NONE);
mISDN_free_bch(&card->bch[1]);
mISDN_free_bch(&card->bch[0]);
mISDN_free_dch(&card->dch);
mISDN_freechannel(&card->dch);
spin_unlock_irqrestore(&card->lock, flags);
hw_mISDNObj.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
spin_lock_irqsave(&hw_mISDNObj.lock, flags);
@ -1856,7 +1850,7 @@ setup_instance(hfcsusb_t * 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]);
mISDN_init_dch(&card->dch);
mISDN_initchannel(&card->dch, MSK_DCHANNEL, MAX_DFRAME_LEN_L1);
card->dch.hw = card;
card->hw_mode = 0;
@ -1906,7 +1900,7 @@ setup_instance(hfcsusb_t * card)
err = setup_hfcsusb(card);
if (err) {
mISDN_free_dch(&card->dch);
mISDN_freechannel(&card->dch);
mISDN_free_bch(&card->bch[1]);
mISDN_free_bch(&card->bch[0]);
spin_lock_irqsave(&hw_mISDNObj.lock, flags);

View File

@ -8,7 +8,7 @@
*/
#include <linux/module.h>
#include "dchannel.h"
#include "channel.h"
#include "isac.h"
#include "arcofi.h"
#include "layer1.h"
@ -19,8 +19,8 @@
#endif
#define DBUSY_TIMER_VALUE 80
#define ARCOFI_USE 1
#define DBUSY_TIMER_VALUE 80
#define ARCOFI_USE 1
const char *isac_revision = "$Revision$";
@ -37,7 +37,7 @@ EXPORT_SYMBOL(mISDN_ISAC_l1hw);
#endif
static inline void
ph_command(dchannel_t *dch, unsigned int command)
ph_command(channel_t *dch, unsigned int command)
{
if (dch->debug & L1_DEB_ISAC)
mISDN_debugprint(&dch->inst, "ph_command %x", command);
@ -48,12 +48,12 @@ ph_command(dchannel_t *dch, unsigned int command)
}
static void
isac_ph_state_change(dchannel_t *dch)
isac_ph_state_change(channel_t *dch)
{
u_int prim = PH_SIGNAL | INDICATION;
u_int para = 0;
switch (dch->ph_state) {
switch (dch->state) {
case (ISAC_IND_RS):
case (ISAC_IND_EI):
ph_command(dch, ISAC_CMD_DUI);
@ -92,7 +92,7 @@ isac_ph_state_change(dchannel_t *dch)
#ifdef OBSOLETE
static void
isac_hwbh(dchannel_t *dch)
isac_hwbh(channel_t *dch)
{
if (dch->debug)
printk(KERN_DEBUG "%s: event %lx\n", __FUNCTION__, dch->event);
@ -110,7 +110,7 @@ isac_hwbh(dchannel_t *dch)
#endif
void
isac_empty_fifo(dchannel_t *dch, int count)
isac_empty_fifo(channel_t *dch, int count)
{
u_char *ptr;
@ -135,24 +135,25 @@ isac_empty_fifo(dchannel_t *dch, int count)
dch->read_fifo(dch->inst.privat, ptr, count);
dch->write_reg(dch->inst.privat, ISAC_CMDR, 0x80);
if (dch->debug & L1_DEB_ISAC_FIFO) {
char *t = dch->dlog;
char *t = dch->log;
t += sprintf(t, "isac_empty_fifo cnt %d", count);
mISDN_QuickHex(t, ptr, count);
mISDN_debugprint(&dch->inst, dch->dlog);
mISDN_debugprint(&dch->inst, dch->log);
}
}
static void
isac_fill_fifo(dchannel_t *dch)
isac_fill_fifo(channel_t *dch)
{
int count, more;
u_char *ptr;
if ((dch->debug & L1_DEB_ISAC) && !(dch->debug & L1_DEB_ISAC_FIFO))
mISDN_debugprint(&dch->inst, "isac_fill_fifo");
count = dch->tx_len - dch->tx_idx;
if (!dch->tx_skb)
return;
count = dch->tx_skb->len - dch->tx_idx;
if (count <= 0)
return;
@ -161,28 +162,28 @@ isac_fill_fifo(dchannel_t *dch)
more = !0;
count = 32;
}
ptr = dch->tx_buf + dch->tx_idx;
ptr = dch->tx_skb->data + dch->tx_idx;
dch->tx_idx += count;
dch->write_fifo(dch->inst.privat, ptr, count);
dch->write_reg(dch->inst.privat, ISAC_CMDR, more ? 0x8 : 0xa);
if (test_and_set_bit(FLG_DBUSY_TIMER, &dch->DFlags)) {
if (test_and_set_bit(FLG_BUSY_TIMER, &dch->Flags)) {
mISDN_debugprint(&dch->inst, "isac_fill_fifo dbusytimer running");
del_timer(&dch->dbusytimer);
del_timer(&dch->timer);
}
init_timer(&dch->dbusytimer);
dch->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
add_timer(&dch->dbusytimer);
init_timer(&dch->timer);
dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
add_timer(&dch->timer);
if (dch->debug & L1_DEB_ISAC_FIFO) {
char *t = dch->dlog;
char *t = dch->log;
t += sprintf(t, "isac_fill_fifo cnt %d", count);
mISDN_QuickHex(t, ptr, count);
mISDN_debugprint(&dch->inst, dch->dlog);
mISDN_debugprint(&dch->inst, dch->log);
}
}
static void
isac_rme_irq(dchannel_t *dch)
isac_rme_irq(channel_t *dch)
{
u_char val;
u_int count;
@ -221,76 +222,74 @@ isac_rme_irq(dchannel_t *dch)
}
static void
isac_xpr_irq(dchannel_t *dch)
isac_xpr_irq(channel_t *dch)
{
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
del_timer(&dch->dbusytimer);
if (dch->tx_idx < dch->tx_len) {
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
del_timer(&dch->timer);
if (dch->tx_skb && dch->tx_idx < dch->tx_skb->len) {
isac_fill_fifo(dch);
} else {
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) {
if (dch->tx_skb)
dev_kfree_skb(dch->tx_skb);
if (test_bit(FLG_TX_NEXT, &dch->Flags)) {
dch->tx_skb = dch->next_skb;
if (dch->tx_skb) {
mISDN_head_t *hh = mISDN_HEAD_P(dch->tx_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);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
dch->tx_idx = 0;
queue_ch_frame(dch, CONFIRM, hh->dinfo, NULL);
isac_fill_fifo(dch);
skb_trim(skb, 0);
if (unlikely(mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_CNF, hh->dinfo, skb))) {
int_error();
dev_kfree_skb(skb);
}
} 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);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
}
} else
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
} else {
dch->tx_skb = NULL;
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
}
}
}
static void
isac_retransmit(dchannel_t *dch)
isac_retransmit(channel_t *dch)
{
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
del_timer(&dch->dbusytimer);
if (test_bit(FLG_TX_BUSY, &dch->DFlags)) {
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
del_timer(&dch->timer);
if (test_bit(FLG_TX_BUSY, &dch->Flags)) {
/* Restart frame */
dch->tx_idx = 0;
isac_fill_fifo(dch);
} else if (dch->tx_skb) { /* should not happen */
int_error();
test_and_set_bit(FLG_TX_BUSY, &dch->Flags);
dch->tx_idx = 0;
isac_fill_fifo(dch);
} else {
printk(KERN_WARNING "mISDN: ISAC XDU no TX_BUSY\n");
mISDN_debugprint(&dch->inst, "ISAC XDU no TX_BUSY");
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) {
if (test_bit(FLG_TX_NEXT, &dch->Flags)) {
dch->tx_skb = dch->next_skb;
if (dch->tx_skb) {
mISDN_head_t *hh = mISDN_HEAD_P(dch->next_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);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
dch->tx_idx = 0;
queue_ch_frame(dch, CONFIRM, hh->dinfo, NULL);
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();
dev_kfree_skb(skb);
}
} else {
printk(KERN_WARNING "isac xdu irq TX_NEXT without skb\n");
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
}
}
}
}
static void
isac_mos_irq(dchannel_t *dch)
isac_mos_irq(channel_t *dch)
{
u_char val;
isac_chip_t *isac = dch->hw;
@ -424,7 +423,7 @@ AfterMOX1:
}
static void
isac_cisq_irq(dchannel_t *dch) {
isac_cisq_irq(channel_t *dch) {
unsigned char val;
val = dch->read_reg(dch->inst.privat, ISAC_CIR0);
@ -433,8 +432,8 @@ isac_cisq_irq(dchannel_t *dch) {
if (val & 2) {
if (dch->debug & L1_DEB_ISAC)
mISDN_debugprint(&dch->inst, "ph_state change %x->%x",
dch->ph_state, (val >> 2) & 0xf);
dch->ph_state = (val >> 2) & 0xf;
dch->state, (val >> 2) & 0xf);
dch->state = (val >> 2) & 0xf;
isac_ph_state_change(dch);
}
if (val & 1) {
@ -445,7 +444,7 @@ isac_cisq_irq(dchannel_t *dch) {
}
static void
isacsx_cic_irq(dchannel_t *dch)
isacsx_cic_irq(channel_t *dch)
{
unsigned char val;
@ -455,14 +454,14 @@ isacsx_cic_irq(dchannel_t *dch)
if (val & ISACSX_CIR0_CIC0) {
if (dch->debug & L1_DEB_ISAC)
mISDN_debugprint(&dch->inst, "ph_state change %x->%x",
dch->ph_state, val >> 4);
dch->ph_state = val >> 4;
dch->state, val >> 4);
dch->state = val >> 4;
isac_ph_state_change(dch);
}
}
static void
isacsx_rme_irq(dchannel_t *dch)
isacsx_rme_irq(channel_t *dch)
{
int count;
unsigned char val;
@ -501,7 +500,7 @@ isacsx_rme_irq(dchannel_t *dch)
}
void
mISDN_isac_interrupt(dchannel_t *dch, u_char val)
mISDN_isac_interrupt(channel_t *dch, u_char val)
{
if (dch->debug & L1_DEB_ISAC)
mISDN_debugprint(&dch->inst, "ISAC interrupt %02x", val);
@ -578,44 +577,22 @@ mISDN_isac_interrupt(dchannel_t *dch, u_char val)
int
mISDN_ISAC_l1hw(mISDNinstance_t *inst, struct sk_buff *skb)
{
dchannel_t *dch;
channel_t *dch;
int ret = 0;
mISDN_head_t *hh;
u_long flags;
hh = mISDN_HEAD_P(skb);
dch = container_of(inst, dchannel_t, inst);
dch = container_of(inst, channel_t, inst);
if (hh->prim == PH_DATA_REQ) {
/* check oversize */
if (skb->len <= 0) {
printk(KERN_WARNING "%s: skb too small\n", __FUNCTION__);
return(-EINVAL);
}
if (skb->len > MAX_DFRAME_LEN_L1) {
printk(KERN_WARNING "%s: skb too large\n", __FUNCTION__);
return(-EINVAL);
}
spin_lock_irqsave(inst->hwlock, flags);
if (dch->next_skb) {
mISDN_debugprint(&dch->inst, " l2l1 next_skb exist this shouldn't happen");
spin_unlock_irqrestore(inst->hwlock, flags);
return(-EBUSY);
}
if (test_and_set_bit(FLG_TX_BUSY, &dch->DFlags)) {
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
dch->next_skb = skb;
spin_unlock_irqrestore(inst->hwlock, flags);
return(0);
} else {
dch->tx_len = skb->len;
memcpy(dch->tx_buf, skb->data, dch->tx_len);
dch->tx_idx = 0;
ret = channel_senddata(dch, hh->dinfo, skb);
if (ret > 0) { /* direct TX */
isac_fill_fifo(dch);
spin_unlock_irqrestore(inst->hwlock, flags);
skb_trim(skb, 0);
return(mISDN_queueup_newhead(inst, 0, PH_DATA_CNF,
hh->dinfo, skb));
ret = 0;
}
spin_unlock_irqrestore(inst->hwlock, flags);
return(ret);
} else if (hh->prim == (PH_SIGNAL | REQUEST)) {
spin_lock_irqsave(inst->hwlock, flags);
if (hh->dinfo == INFO3_P8)
@ -628,9 +605,9 @@ mISDN_ISAC_l1hw(mISDNinstance_t *inst, struct sk_buff *skb)
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
spin_lock_irqsave(inst->hwlock, flags);
if (hh->dinfo == HW_RESET) {
if ((dch->ph_state == ISAC_IND_EI) ||
(dch->ph_state == ISAC_IND_DR) ||
(dch->ph_state == ISAC_IND_RS))
if ((dch->state == ISAC_IND_EI) ||
(dch->state == ISAC_IND_DR) ||
(dch->state == ISAC_IND_RS))
ph_command(dch, ISAC_CMD_TIM);
else
ph_command(dch, ISAC_CMD_RS);
@ -641,10 +618,10 @@ mISDN_ISAC_l1hw(mISDNinstance_t *inst, struct sk_buff *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);
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
del_timer(&dch->dbusytimer);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
del_timer(&dch->timer);
} else if ((hh->dinfo & HW_TESTLOOP) == HW_TESTLOOP) {
u_char tl;
if (dch->type & ISAC_TYPE_ISACSX) {
@ -703,12 +680,12 @@ mISDN_ISAC_l1hw(mISDNinstance_t *inst, struct sk_buff *skb)
}
void
mISDN_isac_free(dchannel_t *dch) {
mISDN_isac_free(channel_t *dch) {
isac_chip_t *isac = dch->hw;
if (dch->dbusytimer.function != NULL) {
del_timer(&dch->dbusytimer);
dch->dbusytimer.function = NULL;
if (dch->timer.function != NULL) {
del_timer(&dch->timer);
dch->timer.function = NULL;
}
if (!isac)
return;
@ -719,12 +696,12 @@ mISDN_isac_free(dchannel_t *dch) {
}
static void
dbusy_timer_handler(dchannel_t *dch)
dbusy_timer_handler(channel_t *dch)
{
int rbch, star;
u_long flags;
if (test_bit(FLG_DBUSY_TIMER, &dch->DFlags)) {
if (test_bit(FLG_BUSY_TIMER, &dch->Flags)) {
spin_lock_irqsave(dch->inst.hwlock, flags);
rbch = dch->read_reg(dch->inst.privat, ISAC_RBCH);
star = dch->read_reg(dch->inst.privat, ISAC_STAR);
@ -732,10 +709,10 @@ dbusy_timer_handler(dchannel_t *dch)
mISDN_debugprint(&dch->inst, "D-Channel Busy RBCH %02x STAR %02x",
rbch, star);
if (rbch & ISAC_RBCH_XAC) { /* D-Channel Busy */
test_and_set_bit(FLG_L1_DBUSY, &dch->DFlags);
test_and_set_bit(FLG_L1_BUSY, &dch->Flags);
} else {
/* discard frame; reset transceiver */
test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags);
test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags);
if (dch->tx_idx) {
dch->tx_idx = 0;
} else {
@ -754,7 +731,7 @@ static char *ISACVer[] =
"2085 V2.3"};
int
mISDN_isac_init(dchannel_t *dch)
mISDN_isac_init(channel_t *dch)
{
isac_chip_t *isac = dch->hw;
u_char val;
@ -762,12 +739,11 @@ mISDN_isac_init(dchannel_t *dch)
if (!isac)
return(-EINVAL);
dch->hw_bh = NULL;
isac->mon_tx = NULL;
isac->mon_rx = NULL;
dch->dbusytimer.function = (void *) dbusy_timer_handler;
dch->dbusytimer.data = (long) dch;
init_timer(&dch->dbusytimer);
dch->timer.function = (void *) dbusy_timer_handler;
dch->timer.data = (long) dch;
init_timer(&dch->timer);
isac->mocr = 0xaa;
if (dch->type & ISAC_TYPE_ISACSX) {
// clear LDD
@ -815,7 +791,7 @@ mISDN_isac_init(dchannel_t *dch)
}
void
mISDN_clear_isac(dchannel_t *dch)
mISDN_clear_isac(channel_t *dch)
{
isac_chip_t *isac = dch->hw;
u_int val, eval;
@ -838,7 +814,7 @@ mISDN_clear_isac(dchannel_t *dch)
}
val = dch->read_reg(dch->inst.privat, ISAC_CIR0);
mISDN_debugprint(&dch->inst, "ISAC CIR0 %x", val);
dch->ph_state = (val >> 2) & 0xf;
dch->state = (val >> 2) & 0xf;
}
#ifdef MODULE

View File

@ -128,9 +128,9 @@ typedef struct isac_chip {
/* interface for the isac module */
extern int mISDN_isac_init(dchannel_t *);
extern void mISDN_isac_free(dchannel_t *);
extern int mISDN_isac_init(channel_t *);
extern void mISDN_isac_free(channel_t *);
extern void mISDN_isac_interrupt(dchannel_t *, u_char);
extern void mISDN_clear_isac(dchannel_t *);
extern void mISDN_isac_interrupt(channel_t *, u_char);
extern void mISDN_clear_isac(channel_t *);
extern int mISDN_ISAC_l1hw(mISDNinstance_t *, struct sk_buff *);

File diff suppressed because it is too large Load Diff

View File

@ -230,9 +230,9 @@ typedef struct _isar_hw {
#define STFAX_ESCAPE 5
#define STFAX_SILDET 6
extern int ISARVersion(bchannel_t *bch, char *s);
extern void isar_int_main(bchannel_t *bch);
extern int init_isar(bchannel_t *bch);
extern void free_isar(bchannel_t *bch);
extern int ISARVersion(channel_t *bch, char *s);
extern void isar_int_main(channel_t *bch);
extern int init_isar(channel_t *bch);
extern void free_isar(channel_t *bch);
extern int isar_down(mISDNinstance_t *, struct sk_buff *);
extern int isar_load_firmware(bchannel_t *bch, u_char *buf, int size);
extern int isar_load_firmware(channel_t *bch, u_char *buf, int size);

View File

@ -36,8 +36,7 @@
#else
#include <linux/isapnp.h>
#endif
#include "dchannel.h"
#include "bchannel.h"
#include "channel.h"
#include "isac.h"
#include "isar.h"
#include "layer1.h"
@ -127,8 +126,8 @@ typedef struct _sedl_fax {
isar_reg_t ir;
isac_chip_t isac_hw;
isar_hw_t isar_hw[2];
dchannel_t dch;
bchannel_t bch[2];
channel_t dch;
channel_t bch[2];
} sedl_fax;
static inline u_char
@ -193,25 +192,27 @@ WriteISACfifo(void *p, u_char * data, int size)
*/
static u_char
ReadISAR(void *p, int mode, u_char offset)
ReadISAR(void *p, u_char offset)
{
if (mode == 0)
return (readreg(((sedl_fax *)p)->addr, ((sedl_fax *)p)->isar, offset));
else if (mode == 1)
byteout(((sedl_fax *)p)->addr, offset);
return(bytein(((sedl_fax *)p)->isar));
return (readreg(((sedl_fax *)p)->addr, ((sedl_fax *)p)->isar, offset));
}
static void
WriteISAR(void *p, int mode, u_char offset, u_char value)
WriteISAR(void *p, u_char offset, u_char value)
{
if (mode == 0)
writereg(((sedl_fax *)p)->addr, ((sedl_fax *)p)->isar, offset, value);
else {
if (mode == 1)
byteout(((sedl_fax *)p)->addr, offset);
byteout(((sedl_fax *)p)->isar, value);
}
writereg(((sedl_fax *)p)->addr, ((sedl_fax *)p)->isar, offset, value);
}
static void
ReadISARfifo(void *p, u_char * data, int size)
{
readfifo(((sedl_fax *)p)->addr, ((sedl_fax *)p)->isar, ISAR_MBOX, data, size);
}
static void
WriteISARfifo(void *p, u_char * data, int size)
{
writefifo(((sedl_fax *)p)->addr, ((sedl_fax *)p)->isar, ISAR_MBOX, data, size);
}
inline void
@ -287,7 +288,7 @@ static void
enable_hwirq(sedl_fax *sf)
{
WriteISAC(sf, ISAC_MASK, 0);
WriteISAR(sf, 0, ISAR_IRQBIT, ISAR_IRQMSK);
WriteISAR(sf, ISAR_IRQBIT, ISAR_IRQMSK);
if (sf->subtyp != SEDL_SPEEDFAX_ISA)
byteout(sf->cfg + TIGER_AUX_IRQMASK, SEDL_TIGER_IRQ_BIT);
}
@ -296,7 +297,7 @@ static void
disable_hwirq(sedl_fax *sf)
{
WriteISAC(sf, ISAC_MASK, 0xFF);
WriteISAR(sf, 0, ISAR_IRQBIT, 0);
WriteISAR(sf, ISAR_IRQBIT, 0);
if (sf->subtyp != SEDL_SPEEDFAX_ISA)
byteout(sf->cfg + TIGER_AUX_IRQMASK, 0);
}
@ -462,10 +463,14 @@ setup_speedfax(sedl_fax *sf)
sf->isar_hw[1].reg = &sf->ir;
sf->bch[0].hw = &sf->isar_hw[0];
sf->bch[1].hw = &sf->isar_hw[1];
sf->bch[0].Read_Reg = &ReadISAR;
sf->bch[0].Write_Reg = &WriteISAR;
sf->bch[1].Read_Reg = &ReadISAR;
sf->bch[1].Write_Reg = &WriteISAR;
sf->bch[0].read_reg = &ReadISAR;
sf->bch[0].write_reg = &WriteISAR;
sf->bch[0].read_fifo = &ReadISARfifo;
sf->bch[0].write_fifo = &WriteISARfifo;
sf->bch[1].read_reg = &ReadISAR;
sf->bch[1].write_reg = &WriteISAR;
sf->bch[1].read_fifo = &ReadISARfifo;
sf->bch[1].write_fifo = &WriteISARfifo;
spin_lock_irqsave(&sf->lock, flags);
disable_hwirq(sf);
ver = ISARVersion(&sf->bch[0], "Sedlbauer:");
@ -492,9 +497,9 @@ release_card(sedl_fax *card) {
free_isar(&card->bch[0]);
mISDN_isac_free(&card->dch);
release_sedlbauer(card);
mISDN_free_bch(&card->bch[1]);
mISDN_free_bch(&card->bch[0]);
mISDN_free_dch(&card->dch);
mISDN_freechannel(&card->bch[1]);
mISDN_freechannel(&card->bch[0]);
mISDN_freechannel(&card->dch);
spin_unlock_irqrestore(&card->lock, flags);
speedfax.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
spin_lock_irqsave(&speedfax.lock, flags);
@ -554,9 +559,9 @@ speedfax_manager(void *data, u_int prim, void *arg) {
switch(prim) {
case MGR_REGLAYER | CONFIRM:
if (channel == 2)
dch_set_para(&card->dch, &inst->st->para);
mISDN_setpara(&card->dch, &inst->st->para);
else
bch_set_para(&card->bch[channel], &inst->st->para);
mISDN_setpara(&card->bch[channel], &inst->st->para);
break;
case MGR_UNREGLAYER | REQUEST:
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
@ -576,9 +581,9 @@ speedfax_manager(void *data, u_int prim, void *arg) {
arg = NULL;
case MGR_ADDSTPARA | INDICATION:
if (channel == 2)
dch_set_para(&card->dch, arg);
mISDN_setpara(&card->dch, arg);
else
bch_set_para(&card->bch[channel], arg);
mISDN_setpara(&card->bch[channel], arg);
break;
case MGR_RELEASE | INDICATION:
if (channel == 2) {
@ -672,7 +677,7 @@ static int __devinit setup_instance(sedl_fax *card)
mISDN_init_instance(&card->dch.inst, &speedfax, card, mISDN_ISAC_l1hw);
sprintf(card->dch.inst.name, "SpeedFax%d", sedl_cnt+1);
mISDN_set_dchannel_pid(&pid, protocol[sedl_cnt], layermask[sedl_cnt]);
mISDN_init_dch(&card->dch);
mISDN_initchannel(&card->dch, MSK_INIT_DCHANNEL, MAX_DFRAME_LEN_L1);
for (i=0; i<2; i++) {
card->bch[i].channel = i;
mISDN_init_instance(&card->bch[i].inst, &speedfax, card, isar_down);
@ -681,15 +686,15 @@ static int __devinit setup_instance(sedl_fax *card)
card->bch[i].debug = debug;
card->bch[i].inst.class_dev.dev = dev;
sprintf(card->bch[i].inst.name, "%s B%d", card->dch.inst.name, i+1);
mISDN_init_bch(&card->bch[i]);
mISDN_initchannel(&card->dch, MSK_INIT_BCHANNEL, MAX_DATA_MEM);
}
printk(KERN_DEBUG "sfax card %p dch %p bch1 %p bch2 %p\n",
card, &card->dch, &card->bch[0], &card->bch[1]);
err = setup_speedfax(card);
if (err) {
mISDN_free_dch(&card->dch);
mISDN_free_bch(&card->bch[1]);
mISDN_free_bch(&card->bch[0]);
mISDN_freechannel(&card->dch);
mISDN_freechannel(&card->bch[1]);
mISDN_freechannel(&card->bch[0]);
spin_lock_irqsave(&speedfax.lock, flags);
list_del(&card->list);
spin_unlock_irqrestore(&speedfax.lock, flags);

View File

@ -26,7 +26,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include "dchannel.h"
#include "channel.h"
#include "bchannel.h"
#include "layer1.h"
#include "helper.h"
@ -60,7 +60,7 @@ typedef struct _w6692pci {
u_char xaddr;
u_char xdata;
w6692_bc wbc[2];
dchannel_t dch;
channel_t dch;
bchannel_t bch[2];
} w6692pci;
@ -139,12 +139,12 @@ ph_command(w6692pci *card, u_char command)
}
static void
W6692_new_ph(dchannel_t *dch)
W6692_new_ph(channel_t *dch)
{
u_int prim = PH_SIGNAL | INDICATION;
u_int para = 0;
switch (dch->ph_state) {
switch (dch->state) {
case W_L1CMD_RST:
ph_command(dch->hw, W_L1CMD_DRC);
mISDN_queue_data(&dch->inst, FLG_MSG_UP, PH_CONTROL | INDICATION, HW_RESET, 0, NULL, 0);
@ -182,7 +182,7 @@ W6692_new_ph(dchannel_t *dch)
static void
W6692_empty_Dfifo(w6692pci *card, int count)
{
dchannel_t *dch = &card->dch;
channel_t *dch = &card->dch;
u_char *ptr;
if ((dch->debug & L1_DEB_ISAC) && !(dch->debug & L1_DEB_ISAC_FIFO))
@ -206,18 +206,18 @@ W6692_empty_Dfifo(w6692pci *card, int count)
insb(card->addr + W_D_RFIFO, ptr, count);
WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
if (dch->debug & L1_DEB_ISAC_FIFO) {
char *t = dch->dlog;
char *t = dch->log;
t += sprintf(t, "empty_Dfifo cnt %d", count);
mISDN_QuickHex(t, ptr, count);
mISDN_debugprint(&dch->inst, dch->dlog);
mISDN_debugprint(&dch->inst, dch->log);
}
}
static void
W6692_fill_Dfifo(w6692pci *card)
{
dchannel_t *dch = &card->dch;
channel_t *dch = &card->dch;
int count;
u_char *ptr;
u_char cmd = W_D_CMDR_XMS;
@ -225,67 +225,71 @@ W6692_fill_Dfifo(w6692pci *card)
if ((dch->debug & L1_DEB_ISAC) && !(dch->debug & L1_DEB_ISAC_FIFO))
mISDN_debugprint(&dch->inst, "fill_Dfifo");
count = dch->tx_len - dch->tx_idx;
if (!dch->tx_skb)
return;
count = dch->tx_skb->len - dch->tx_idx;
if (count <= 0)
return;
if (count > 32) {
if (count > 32)
count = 32;
} else
else
cmd |= W_D_CMDR_XME;
ptr = dch->tx_buf + dch->tx_idx;
ptr = dch->tx_skb->data + dch->tx_idx;
dch->tx_idx += count;
outsb(card->addr + W_D_XFIFO, ptr, count);
WriteW6692(card, W_D_CMDR, cmd);
if (test_and_set_bit(FLG_DBUSY_TIMER, &dch->DFlags)) {
if (test_and_set_bit(FLG_BUSY_TIMER, &dch->Flags)) {
mISDN_debugprint(&dch->inst, "fill_Dfifo dbusytimer running");
del_timer(&dch->dbusytimer);
del_timer(&dch->timer);
}
init_timer(&dch->dbusytimer);
dch->dbusytimer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
add_timer(&dch->dbusytimer);
init_timer(&dch->timer);
dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
add_timer(&dch->timer);
if (dch->debug & L1_DEB_ISAC_FIFO) {
char *t = dch->dlog;
char *t = dch->log;
t += sprintf(t, "fill_Dfifo cnt %d", count);
mISDN_QuickHex(t, ptr, count);
mISDN_debugprint(&dch->inst, dch->dlog);
mISDN_debugprint(&dch->inst, dch->log);
}
}
static void
d_retransmit(w6692pci *card)
{
dchannel_t *dch = &card->dch;
channel_t *dch = &card->dch;
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
del_timer(&dch->dbusytimer);
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
del_timer(&dch->timer);
#ifdef FIXME
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
dchannel_sched_event(dch, D_CLEARBUSY);
#endif
if (test_bit(FLG_TX_BUSY, &dch->DFlags)) {
if (test_bit(FLG_TX_BUSY, &dch->Flags)) {
/* Restart frame */
dch->tx_idx = 0;
W6692_fill_Dfifo(card);
} else if (dch->tx_skb) { /* should not happen */
int_error();
test_and_set_bit(FLG_TX_BUSY, &dch->Flags);
dch->tx_idx = 0;
W6692_fill_Dfifo(card);
} else {
printk(KERN_WARNING "mISDN: w6692 XDU no TX_BUSY\n");
mISDN_debugprint(&dch->inst, "XDU no TX_BUSY");
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);
if (test_bit(FLG_TX_NEXT, &dch->Flags)) {
dch->tx_skb = dch->next_skb;
if (dch->tx_skb) {
mISDN_head_t *hh = mISDN_HEAD_P(dch->tx_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);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
dch->tx_idx = 0;
queue_ch_frame(dch, CONFIRM, hh->dinfo, NULL);
W6692_fill_Dfifo(card);
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);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
}
}
}
@ -336,43 +340,44 @@ handle_rxD(w6692pci *card) {
static void
handle_txD(w6692pci *card) {
register dchannel_t *dch = &card->dch;
register channel_t *dch = &card->dch;
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
del_timer(&dch->dbusytimer);
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
del_timer(&dch->timer);
#ifdef FIXME
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
dchannel_sched_event(dch, D_CLEARBUSY);
#endif
if (dch->tx_idx < dch->tx_len) {
if (dch->tx_skb && dch->tx_idx < dch->tx_skb->len) {
W6692_fill_Dfifo(card);
} else {
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);
if (dch->tx_skb)
dev_kfree_skb(dch->tx_skb);
if (test_bit(FLG_TX_NEXT, &dch->Flags)) {
dch->tx_skb = dch->next_skb;
if (dch->tx_skb) {
mISDN_head_t *hh = mISDN_HEAD_P(dch->tx_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);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
dch->tx_idx = 0;
queue_ch_frame(dch, CONFIRM, hh->dinfo, NULL);
W6692_fill_Dfifo(card);
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);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
}
} else
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
} else {
dch->tx_skb = NULL;
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
}
}
}
static void
handle_statusD(w6692pci *card) {
register dchannel_t *dch = &card->dch;
register channel_t *dch = &card->dch;
u_char exval, v1, cir;
exval = ReadW6692(card, W_D_EXIR);
@ -410,8 +415,8 @@ handle_statusD(w6692pci *card) {
v1 = cir & W_CIR_COD_MASK;
if (card->dch.debug & L1_DEB_ISAC)
mISDN_debugprint(&card->dch.inst, "ph_state_change %x -> %x",
dch->ph_state, v1);
dch->ph_state = v1;
dch->state, v1);
dch->state = v1;
if (card->led & W_LED1_S0STATUS) {
switch (v1) {
case W_L1IND_AI8:
@ -830,13 +835,13 @@ w6692_interrupt(int intno, void *dev_id, struct pt_regs *regs)
}
static void
dbusy_timer_handler(dchannel_t *dch)
dbusy_timer_handler(channel_t *dch)
{
w6692pci *card = dch->hw;
int rbch, star;
u_long flags;
if (test_bit(FLG_DBUSY_TIMER, &dch->DFlags)) {
if (test_bit(FLG_BUSY_TIMER, &dch->Flags)) {
spin_lock_irqsave(dch->inst.hwlock, flags);
rbch = ReadW6692(card, W_D_RBCH);
star = ReadW6692(card, W_D_STAR);
@ -844,10 +849,10 @@ dbusy_timer_handler(dchannel_t *dch)
mISDN_debugprint(&dch->inst, "D-Channel Busy RBCH %02x STAR %02x",
rbch, star);
if (star & W_D_STAR_XBZ) { /* D-Channel Busy */
test_and_set_bit(FLG_L1_DBUSY, &dch->DFlags);
test_and_set_bit(FLG_L1_BUSY, &dch->Flags);
} else {
/* discard frame; reset transceiver */
test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags);
test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags);
if (dch->tx_idx) {
dch->tx_idx = 0;
} else {
@ -865,10 +870,9 @@ void initW6692(w6692pci *card)
{
u_char val;
card->dch.hw_bh = W6692_new_ph;
card->dch.dbusytimer.function = (void *) dbusy_timer_handler;
card->dch.dbusytimer.data = (u_long) &card->dch;
init_timer(&card->dch.dbusytimer);
card->dch.timer.function = (void *) dbusy_timer_handler;
card->dch.timer.data = (u_long) &card->dch;
init_timer(&card->dch.timer);
mode_w6692(&card->bch[0], 0, -1);
mode_w6692(&card->bch[1], 1, -1);
WriteW6692(card, W_D_CTL, 0x00);
@ -876,7 +880,7 @@ void initW6692(w6692pci *card)
WriteW6692(card, W_D_SAM, 0xff);
WriteW6692(card, W_D_TAM, 0xff);
WriteW6692(card, W_D_MODE, W_D_MODE_RACT);
card->dch.ph_state = W_L1CMD_RST;
card->dch.state = W_L1CMD_RST;
ph_command(card, W_L1CMD_RST);
ph_command(card, W_L1CMD_ECK);
/* enable all IRQ but extern */
@ -1092,7 +1096,7 @@ w6692_l2l1B(mISDNinstance_t *inst, struct sk_buff *skb)
static int
w6692_l1hwD(mISDNinstance_t *inst, struct sk_buff *skb)
{
dchannel_t *dch = container_of(inst, dchannel_t, inst);
channel_t *dch = container_of(inst, channel_t, inst);
int ret = 0;
mISDN_head_t *hh = mISDN_HEAD_P(skb);
u_long flags;
@ -1114,20 +1118,17 @@ w6692_l1hwD(mISDNinstance_t *inst, struct sk_buff *skb)
spin_unlock_irqrestore(inst->hwlock, flags);
return(-EBUSY);
}
if (test_and_set_bit(FLG_TX_BUSY, &dch->DFlags)) {
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
if (test_and_set_bit(FLG_TX_BUSY, &dch->Flags)) {
test_and_set_bit(FLG_TX_NEXT, &dch->Flags);
dch->next_skb = skb;
spin_unlock_irqrestore(inst->hwlock, flags);
return(0);
} else {
dch->tx_len = skb->len;
memcpy(dch->tx_buf, skb->data, dch->tx_len);
dch->tx_skb = skb;
dch->tx_idx = 0;
queue_ch_frame(dch, CONFIRM, hh->dinfo, NULL);
W6692_fill_Dfifo(dch->hw);
spin_unlock_irqrestore(inst->hwlock, flags);
return(mISDN_queueup_newhead(inst, 0, PH_DATA_CNF,
hh->dinfo, skb));
}
spin_unlock_irqrestore(inst->hwlock, flags);
return(0);
} else if (hh->prim == (PH_SIGNAL | REQUEST)) {
spin_lock_irqsave(inst->hwlock, flags);
if (hh->dinfo == INFO3_P8)
@ -1140,7 +1141,7 @@ w6692_l1hwD(mISDNinstance_t *inst, struct sk_buff *skb)
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
spin_lock_irqsave(inst->hwlock, flags);
if (hh->dinfo == HW_RESET) {
if (dch->ph_state != W_L1IND_DRD)
if (dch->state != W_L1IND_DRD)
ph_command(dch->hw, W_L1CMD_RST);
ph_command(dch->hw, W_L1CMD_ECK);
} else if (hh->dinfo == HW_POWERUP) {
@ -1150,12 +1151,12 @@ w6692_l1hwD(mISDNinstance_t *inst, struct sk_buff *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);
if (test_and_clear_bit(FLG_DBUSY_TIMER, &dch->DFlags))
del_timer(&dch->dbusytimer);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
del_timer(&dch->timer);
#ifdef FIXME
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
dchannel_sched_event(dch, D_CLEARBUSY);
#endif
} else if ((hh->dinfo & HW_TESTLOOP) == HW_TESTLOOP) {
@ -1235,7 +1236,7 @@ release_card(w6692pci *card)
release_region(card->addr, 256);
mISDN_free_bch(&card->bch[1]);
mISDN_free_bch(&card->bch[0]);
mISDN_free_dch(&card->dch);
mISDN_freechannel(&card->dch);
spin_unlock_irqrestore(&card->lock, flags);
w6692.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
spin_lock_irqsave(&w6692.lock, flags);
@ -1288,7 +1289,7 @@ w6692_manager(void *data, u_int prim, void *arg) {
switch(prim) {
case MGR_REGLAYER | CONFIRM:
if (channel == 2)
dch_set_para(&card->dch, &inst->st->para);
mISDN_setpara(&card->dch, &inst->st->para);
else
bch_set_para(&card->bch[channel], &inst->st->para);
break;
@ -1310,7 +1311,7 @@ w6692_manager(void *data, u_int prim, void *arg) {
arg = NULL;
case MGR_ADDSTPARA | INDICATION:
if (channel == 2)
dch_set_para(&card->dch, arg);
mISDN_setpara(&card->dch, arg);
else
bch_set_para(&card->bch[channel], arg);
break;
@ -1376,7 +1377,7 @@ static int __devinit setup_instance(w6692pci *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);
mISDN_initchannel(&card->dch, MSK_DCHANNEL, MAX_DFRAME_LEN_L1);
card->dch.hw = card;
for (i=0; i<2; i++) {
card->bch[i].channel = i;
@ -1394,7 +1395,7 @@ static int __devinit setup_instance(w6692pci *card)
card, &card->dch, &card->bch[0], &card->bch[1]);
err = setup_w6692(card);
if (err) {
mISDN_free_dch(&card->dch);
mISDN_freechannel(&card->dch);
mISDN_free_bch(&card->bch[1]);
mISDN_free_bch(&card->bch[0]);
list_del(&card->list);

View File

@ -92,7 +92,7 @@ static void release_card(xhfc_hw * hw);
/* Physical S/U commands to control Line Interface */
/****************************************************/
static void
xhfc_ph_command(dchannel_t * dch, u_char command)
xhfc_ph_command(channel_t * dch, u_char command)
{
xhfc_hw *hw = dch->hw;
__u8 pt = hw->chan[dch->channel].port;
@ -288,7 +288,7 @@ l1_timer_expire_t4(dchannel_t * dch)
/* Line Interface State handler */
/*********************************/
static void
su_new_state(dchannel_t * dch)
su_new_state(channel_t * dch)
{
u_int prim = 0;
@ -299,18 +299,16 @@ su_new_state(dchannel_t * dch)
if (hw->port[pt].mode & PORT_MODE_TE) {
if ((dch->debug) & (debug & DEBUG_HFC_S0_STATES))
mISDN_debugprint(&dch->inst,
"%s: TE %d",
__FUNCTION__, dch->ph_state);
mISDN_debugprint(&dch->inst, "%s: TE %d",
__FUNCTION__, dch->state);
if (dch->ph_state < 4 || dch->ph_state >= 7)
if (dch->state < 4 || dch->state >= 7)
l1_timer_stop_t3(dch);
if (dch->ph_state >= 7)
if (dch->state >= 7)
l1_timer_stop_t4(dch);
switch (dch->ph_state) {
switch (dch->state) {
case (0):
case (1):
case (2):
@ -371,11 +369,10 @@ su_new_state(dchannel_t * dch)
} else if (hw->port[pt].mode & PORT_MODE_NT) {
if ((dch->debug) & (debug & DEBUG_HFC_S0_STATES))
mISDN_debugprint(&dch->inst,
"%s: NT %d",
__FUNCTION__, dch->ph_state);
mISDN_debugprint(&dch->inst, "%s: NT %d",
__FUNCTION__, dch->state);
switch (dch->ph_state) {
switch (dch->state) {
case (1):
dch->l1_up = 0;
@ -435,7 +432,7 @@ su_new_state(dchannel_t * dch)
static int
xhfc_l1_from_up(mISDNinstance_t *inst, struct sk_buff *skb)
{
dchannel_t *dch = container_of(inst, dchannel_t, inst);
channel_t *dch = container_of(inst, channel_t, inst);
int ret = 0;
mISDN_head_t *hh = mISDN_HEAD_P(skb);
xhfc_hw *hw = inst->privat;
@ -497,7 +494,7 @@ xhfc_l1_from_up(mISDNinstance_t *inst, struct sk_buff *skb)
/* check for pending next_skb */
spin_lock_irqsave(inst->hwlock, flags);
if (dch->next_skb) {
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
test_and_set_bit(FLG_TX_NEXT, &dch->Flags);
dch->next_skb = skb;
spin_unlock_irqrestore(inst->hwlock, flags);
mISDN_debugprint(&dch->inst, "pending dch->next_skb!\n");
@ -505,13 +502,13 @@ xhfc_l1_from_up(mISDNinstance_t *inst, struct sk_buff *skb)
return (0);
}
if (test_and_set_bit(FLG_TX_BUSY, &dch->DFlags)) {
if (test_and_set_bit(FLG_TX_BUSY, &dch->Flags)) {
if ((dch->debug) && (debug & DEBUG_HFC_DTRACE)) {
mISDN_debugprint(&dch->inst, "channel(%i) busy, attaching dch->next_skb!\n",
dch->channel,
dch->channel,
skb->len);
}
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
test_and_set_bit(FLG_TX_NEXT, &dch->Flags);
dch->next_skb = skb;
spin_unlock_irqrestore(inst->hwlock, flags);
return (0);
@ -684,7 +681,7 @@ xhfc_manager(void *data, u_int prim, void *arg)
struct sk_buff *skb;
int channel = -1;
int i;
dchannel_t *dch = NULL;
channel_t *dch = NULL;
bchannel_t *bch = NULL;
u_long flags;
@ -730,7 +727,7 @@ xhfc_manager(void *data, u_int prim, void *arg)
switch (prim) {
case MGR_REGLAYER | CONFIRM:
if (dch)
dch_set_para(dch, &inst->st->para);
mISDN_setpara(dch, &inst->st->para);
if (bch)
bch_set_para(bch, &inst->st->para);
break;
@ -752,7 +749,7 @@ xhfc_manager(void *data, u_int prim, void *arg)
arg = NULL;
case MGR_ADDSTPARA | INDICATION:
if (dch)
dch_set_para(dch, arg);
mISDN_setpara(dch, arg);
if (bch)
bch_set_para(bch, arg);
break;
@ -808,32 +805,29 @@ xhfc_manager(void *data, u_int prim, void *arg)
int
next_d_tx_frame(xhfc_hw * hw, __u8 channel)
{
dchannel_t *dch = hw->chan[channel].dch;
channel_t *dch = hw->chan[channel].dch;
if (test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags)) {
struct sk_buff *skb = dch->next_skb;
if (skb) {
mISDN_head_t *hh = mISDN_HEAD_P(skb);
if(dch->tx_skb)
dev_kfree_skb(dch->tx_skb);
if (test_and_clear_bit(FLG_TX_NEXT, &dch->Flags)) {
dch->tx_skb = dch->next_skb;
if (dch->tx_skb) {
mISDN_head_t *hh = mISDN_HEAD_P(dch->tx_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);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
dch->tx_idx = 0;
skb_trim(skb, 0);
if (mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_CNF, hh->dinfo, skb))
dev_kfree_skb(skb);
queue_ch_frame(dch, CONFIRM, hh->dinfo, NULL);
return (1);
} else {
printk(KERN_WARNING
"%s channel(%i) TX_NEXT without skb\n",
hw->card_name, channel);
test_and_clear_bit(FLG_TX_NEXT, &dch->DFlags);
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
test_and_clear_bit(FLG_TX_NEXT, &dch->Flags);
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
}
} else {
test_and_clear_bit(FLG_TX_BUSY, &dch->DFlags);
dch->tx_skb = NULL;
test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
}
return (0);
}
@ -910,7 +904,7 @@ void
xhfc_write_fifo(xhfc_hw * hw, __u8 channel)
{
__u8 *buf = NULL;
int *len = NULL, *idx = NULL;
int len = 0, *idx = NULL;
mISDNinstance_t *inst = NULL;
__u8 hdlc = 0;
__u8 fcnt, tcnt, i;
@ -919,21 +913,23 @@ xhfc_write_fifo(xhfc_hw * hw, __u8 channel)
__u8 fstat;
__u8 *data;
dchannel_t *dch = hw->chan[channel].dch;
channel_t *dch = hw->chan[channel].dch;
bchannel_t *bch = hw->chan[channel].bch;
/* get skb, fifo & mode */
if (dch) {
inst = &dch->inst;
buf = dch->tx_buf;
len = &dch->tx_len;
if (!dch->tx_skb)
return;
buf = dch->tx_skb->data;
len = dch->tx_skb->len;
idx = &dch->tx_idx;
hdlc = 1;
}
if (bch) {
inst = &bch->inst;
buf = bch->tx_buf;
len = &bch->tx_len;
len = bch->tx_len;
idx = &bch->tx_idx;
if (bch->protocol == ISDN_PID_L1_B_64HDLC)
hdlc = 1;
@ -948,12 +944,12 @@ xhfc_write_fifo(xhfc_hw * hw, __u8 channel)
send_buffer:
if (*len) {
if (len) {
xhfc_selfifo(hw, (channel * 2));
fstat = read_xhfc(hw, A_FIFO_STA);
free = (hw->max_z - (read_xhfc(hw, A_USAGE)));
tcnt = ((free >= (*len - *idx)) ? (*len - *idx) : free);
tcnt = ((free >= (len - *idx)) ? (len - *idx) : free);
f1 = read_xhfc(hw, A_F1);
f2 = read_xhfc(hw, A_F2);
@ -963,7 +959,7 @@ xhfc_write_fifo(xhfc_hw * hw, __u8 channel)
if (debug & DEBUG_HFC_FIFO) {
mISDN_debugprint(inst,
"%s channel(%i) len(%i) idx(%i) f1(%i) f2(%i) fcnt(%i) tcnt(%i) free(%i) fstat(%i)",
__FUNCTION__, channel, *len, *idx,
__FUNCTION__, channel, len, *idx,
f1, f2, fcnt, tcnt, free, fstat);
}
@ -1008,7 +1004,7 @@ xhfc_write_fifo(xhfc_hw * hw, __u8 channel)
if (*idx == *len) {
if (*idx == len) {
if (hdlc) {
/* terminate frame */
xhfc_inc_f(hw);
@ -1037,49 +1033,45 @@ xhfc_write_fifo(xhfc_hw * hw, __u8 channel)
}
}
*len = 0;
len = 0;
if (dch) {
if (debug & DEBUG_HFC_DTRACE)
mISDN_debugprint(&dch->
inst,
"TX frame channel(%i) completed",
channel);
mISDN_debugprint(&dch->inst,
"TX frame channel(%i) completed",
channel);
if (next_d_tx_frame(hw, channel)) {
if (debug & DEBUG_HFC_DTRACE)
mISDN_debugprint
(&dch->inst,
"channel(%i) has next_d_tx_frame",
channel);
mISDN_debugprint(&dch->inst,
"channel(%i) has next_d_tx_frame",
channel);
buf = dch->tx_skb->data;
len = dch->tx_skb->len;
}
}
if (bch) {
if (debug & DEBUG_HFC_BTRACE)
mISDN_debugprint(&bch->inst,
"TX frame channel(%i) completed",
channel);
"TX frame channel(%i) completed",
channel);
if (next_b_tx_frame(hw, channel)) {
if (debug & DEBUG_HFC_BTRACE)
mISDN_debugprint
(&bch->inst,
"channel(%i) has next_b_tx_frame",
channel);
mISDN_debugprint(&bch->inst,
"channel(%i) has next_b_tx_frame",
channel);
len = bch->tx_len;
if ((free - tcnt) > 8) {
if (debug & DEBUG_HFC_BTRACE)
mISDN_debugprint
(&bch->inst,
"continue immediatetly",
channel);
mISDN_debugprint(&bch->inst,
"continue immediatetly",
channel);
goto send_buffer;
}
}
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
}
} else {
/* tx buffer not complete, but fifo filled to maximum */
xhfc_selfifo(hw, (channel * 2));
@ -1107,7 +1099,7 @@ xhfc_read_fifo(xhfc_hw * hw, __u8 channel)
struct sk_buff *skb; /* data buffer for upper layer */
__u16 i;
dchannel_t *dch = hw->chan[channel].dch;
channel_t *dch = hw->chan[channel].dch;
bchannel_t *bch = hw->chan[channel].bch;
if (dch) {
@ -1303,7 +1295,7 @@ static void
xhfc_bh_handler(unsigned long ul_hw)
{
xhfc_hw *hw = (xhfc_hw *) ul_hw;
dchannel_t *dch;
channel_t *dch;
int i;
reg_a_su_rd_sta su_state;
@ -1321,7 +1313,7 @@ xhfc_bh_handler(unsigned long ul_hw)
if (hw->chan[i].dch)
if (test_bit
(FLG_TX_BUSY,
&hw->chan[i].dch->DFlags)) {
&hw->chan[i].dch->Flags)) {
xhfc_write_fifo(hw, i);
}
@ -1371,8 +1363,8 @@ xhfc_bh_handler(unsigned long ul_hw)
dch = hw->chan[(i << 2) + 2].dch;
if (dch) {
if (su_state.bit.v_su_sta != dch->ph_state) {
dch->ph_state = su_state.bit.v_su_sta;
if (su_state.bit.v_su_sta != dch->state) {
dch->state = su_state.bit.v_su_sta;
su_new_state(dch);
}
}
@ -1598,7 +1590,7 @@ release_channels(xhfc_hw * hw)
printk(KERN_DEBUG
"%s %s: free D-channel %d\n",
hw->card_name, __FUNCTION__, i);
mISDN_free_dch(hw->chan[i].dch);
mISDN_freechannel(hw->chan[i].dch);
hw_mISDNObj.ctrl(&hw->chan[i].dch->inst, MGR_UNREGLAYER | REQUEST, NULL);
kfree(hw->chan[i].dch);
hw->chan[i].dch = NULL;
@ -1866,7 +1858,7 @@ init_mISDN_channels(xhfc_hw * hw)
int pt;
int ch;
int b;
dchannel_t *dch;
channel_t *dch;
bchannel_t *bch;
mISDN_pid_t pid;
u_long flags;
@ -1886,12 +1878,12 @@ init_mISDN_channels(xhfc_hw * hw)
hw->chan[ch].port = pt;
dch = kmalloc(sizeof(dchannel_t), GFP_ATOMIC);
dch = kmalloc(sizeof(channel_t), GFP_ATOMIC);
if (!dch) {
err = -ENOMEM;
goto free_channels;
}
memset(dch, 0, sizeof(dchannel_t));
memset(dch, 0, sizeof(channel_t));
dch->channel = ch;
dch->debug = debug;
dch->inst.obj = &hw_mISDNObj;
@ -1907,11 +1899,9 @@ init_mISDN_channels(xhfc_hw * hw)
err = -ENOMEM;
goto free_channels;
}
if (mISDN_init_dch(dch)) {
err = -ENOMEM;
err = mISDN_initchannel(dch, MSK_DCHANNEL, MAX_DFRAME_LEN_L1);
if (err)
goto free_channels;
}
dch->hw = hw;
hw->chan[ch].dch = dch;
@ -2005,8 +1995,7 @@ init_mISDN_channels(xhfc_hw * hw)
goto free_channels;
}
dch->hw_bh = su_new_state;
dch->ph_state = 0;
dch->state = 0;
for (b = 0; b < 2; b++) {
bch = hw->chan[(pt << 2) + b].bch;

View File

@ -25,7 +25,7 @@
#define _XHFC_SU_H_
#include <linux/timer.h>
#include "dchannel.h"
#include "channel.h"
#include "bchannel.h"
#include "xhfc24succ.h"
@ -119,7 +119,7 @@ typedef struct {
/* channel struct for each fifo */
typedef struct {
bchannel_t *bch;
dchannel_t *dch;
channel_t *dch;
int rx_idx; /* for D-channel */
__u8 *rx_buf; /* for D-channel */
int port; /* index pointer to port struct */