changes for 2.1

This commit is contained in:
Karsten Keil 1997-10-29 19:07:54 +00:00
parent 78c72820b9
commit b6aeeb8cba
11 changed files with 599 additions and 144 deletions

View File

@ -18,6 +18,7 @@ ifeq ($(CONFIG_HISAX_1TR6),y)
endif
ISAC_OBJ :=
ARCOFI_OBJ :=
HSCX_OBJ :=
HFC_OBJ :=
@ -43,6 +44,7 @@ ifeq ($(CONFIG_HISAX_ELSA),y)
O_OBJS += elsa.o
ISAC_OBJ := isac.o
HSCX_OBJ := hscx.o
ARCOFI_OBJ := arcofi.o
endif
ifeq ($(CONFIG_HISAX_IX1MICROR2),y)
@ -75,8 +77,20 @@ ifeq ($(CONFIG_HISAX_SEDLBAUER),y)
HSCX_OBJ := hscx.o
endif
ifeq ($(CONFIG_HISAX_SPORTSTER),y)
O_OBJS += sportster.o
ISAC_OBJ := isac.o
HSCX_OBJ := hscx.o
endif
O_OBJS += config.o $(ISAC_OBJ) $(HSCX_OBJ) $(HFC_OBJ)
ifeq ($(CONFIG_HISAX_MIC),y)
O_OBJS += mic.o
ISAC_OBJ := isac.o
HSCX_OBJ := hscx.o
endif
O_OBJS += config.o $(ISAC_OBJ) $(HSCX_OBJ) $(HFC_OBJ) $(ARCOFI_OBJ)
O_TARGET :=

View File

@ -5,6 +5,11 @@
*
*
* $Log$
* Revision 2.3 1997/10/01 09:21:33 fritz
* Removed old compatibility stuff for 2.0.X kernels.
* From now on, this code is for 2.1.X ONLY!
* Old stuff is still in the separate branch.
*
* Revision 2.2 1997/09/11 17:24:46 keil
* Add new cards
*
@ -146,17 +151,31 @@
#ifdef CONFIG_HISAX_TELEINT
#undef DEFAULT_CARD
#undef DEFAULT_CFG
#define DEFAULT_CARD ISDN_CTYPE_DYNALINK
#define DEFAULT_CARD ISDN_CTYPE_TELEINT
#define DEFAULT_CFG {5,0x300,0}
#endif
#ifdef CONFIG_HISAX_SEDLBAUER
#undef DEFAULT_CARD
#undef DEFAULT_CFG
#define DEFAULT_CARD ISDN_CTYPE_DYNALINK
#define DEFAULT_CARD ISDN_CTYPE_SEDLBAUER
#define DEFAULT_CFG {11,0x270,0}
#endif
#ifdef CONFIG_HISAX_SPORTSTER
#undef DEFAULT_CARD
#undef DEFAULT_CFG
#define DEFAULT_CARD ISDN_CTYPE_SPORTSTER
#define DEFAULT_CFG {5,0x268,0}
#endif
#ifdef CONFIG_HISAX_MIC
#undef DEFAULT_CARD
#undef DEFAULT_CFG
#define DEFAULT_CARD ISDN_CTYPE_MIC
#define DEFAULT_CFG {12,0x3e0,0}
#endif
#ifdef CONFIG_HISAX_1TR6
#define DEFAULT_PROTO ISDN_PTYPE_1TR6
#define DEFAULT_PROTO_NAME "1TR6"
@ -355,7 +374,7 @@ HiSax_init(void)
r += sprintf(r, "%s", HiSax_getrev(tmp));
printk(KERN_NOTICE "HiSax: Driver for Siemens chip set ISDN cards\n");
printk(KERN_NOTICE "HiSax: Version 2.4\n");
printk(KERN_NOTICE "HiSax: Version 2.6\n");
printk(KERN_NOTICE "HiSax: Revisions %s\n", rev);
#ifdef MODULE
@ -399,9 +418,13 @@ HiSax_init(void)
case ISDN_CTYPE_DYNALINK:
case ISDN_CTYPE_TELEINT:
case ISDN_CTYPE_SEDLBAUER:
case ISDN_CTYPE_SPORTSTER:
case ISDN_CTYPE_MIC:
cards[i].para[0] = irq[i];
cards[i].para[1] = io[i];
break;
case ISDN_CTYPE_ELSA_PCI:
break;
}
}
if (!nzproto) {
@ -423,6 +446,7 @@ HiSax_init(void)
CallcNew();
Isdnl2New();
TeiNew();
Isdnl1New();
if (HiSax_inithardware()) {
/* Install only, if at least one card found */
/* No symbols to export, hide all symbols */
@ -433,6 +457,7 @@ HiSax_init(void)
#endif
return (0);
} else {
Isdnl1Free();
TeiFree();
Isdnl2Free();
CallcFree();

View File

@ -6,6 +6,9 @@
*
*
* $Log$
* Revision 1.1 1997/09/11 17:31:33 keil
* Common part for HFC 2BS0 based cards
*
*
*/
@ -200,7 +203,6 @@ hfc_empty_fifo(struct BCState *bcs, int count)
if (!(skb = dev_alloc_skb(count - 3)))
printk(KERN_WARNING "HFC: receive out of memory\n");
else {
SET_SKB_FREE(skb);
ptr = skb_put(skb, count - 3);
idx = 0;
cip = HFC_CIP | HFC_FIFO_OUT | HFC_REC | HFC_CHANNEL(bcs->channel);
@ -287,7 +289,7 @@ hfc_fill_fifo(struct BCState *bcs)
}
count = GetFreeFifoBytes(bcs);
if (cs->debug & L1_DEB_HSCX) {
sprintf(tmp, "hfc_fill_fifo %d count(%ld/%d)",
sprintf(tmp, "hfc_fill_fifo %d count(%d/%d)",
bcs->channel, bcs->hw.hfc.tx_skb->len,
count);
debugl1(cs, tmp);
@ -306,15 +308,18 @@ hfc_fill_fifo(struct BCState *bcs)
debugl1(cs, "FIFO Send BUSY error");
printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel);
} else {
bcs->tx_cnt -= bcs->hw.hfc.tx_skb->len;
count = bcs->hw.hfc.tx_skb->len;
bcs->tx_cnt -= count;
if (PACKET_NOACK == bcs->hw.hfc.tx_skb->pkt_type)
count = -1;
dev_kfree_skb(bcs->hw.hfc.tx_skb, FREE_WRITE);
bcs->hw.hfc.tx_skb = NULL;
WaitForBusy(cs);
WaitNoBusy(cs);
cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F1_INC | HFC_SEND | HFC_CHANNEL(bcs->channel));
if (bcs->st->lli.l1writewakeup)
bcs->st->lli.l1writewakeup(bcs->st);
bcs->Flag &= ~BC_FLG_BUSY;
if (bcs->st->lli.l1writewakeup && (count >= 0))
bcs->st->lli.l1writewakeup(bcs->st, count);
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
}
restore_flags(flags);
return;
@ -376,16 +381,16 @@ main_irq_hfc(struct BCState *bcs)
cli();
if (bcs->hw.hfc.tx_skb) {
transmit = 1;
bcs->Flag |= BC_FLG_BUSY;
test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
hfc_fill_fifo(bcs);
if (bcs->Flag & BC_FLG_BUSY)
if (test_bit(BC_FLG_BUSY, &bcs->Flag))
transmit = 0;
} else {
if ((bcs->hw.hfc.tx_skb = skb_dequeue(&bcs->squeue))) {
transmit = 1;
bcs->Flag |= BC_FLG_BUSY;
test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
hfc_fill_fifo(bcs);
if (bcs->Flag & BC_FLG_BUSY)
if (test_bit(BC_FLG_BUSY, &bcs->Flag))
transmit = 0;
} else {
transmit = 0;
@ -454,7 +459,7 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
long flags;
switch (pr) {
case (PH_DATA):
case (PH_DATA_REQ):
save_flags(flags);
cli();
if (st->l1.bcs->hw.hfc.tx_skb) {
@ -462,29 +467,29 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
restore_flags(flags);
} else {
st->l1.bcs->hw.hfc.tx_skb = skb;
st->l1.bcs->Flag |= BC_FLG_BUSY;
test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
restore_flags(flags);
}
break;
case (PH_DATA_PULLED):
case (PH_PULL_IND):
if (st->l1.bcs->hw.hfc.tx_skb) {
printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
break;
}
save_flags(flags);
cli();
st->l1.bcs->Flag |= BC_FLG_BUSY;
test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
st->l1.bcs->hw.hfc.tx_skb = skb;
st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
restore_flags(flags);
break;
case (PH_REQUEST_PULL):
case (PH_PULL_REQ):
if (!st->l1.bcs->hw.hfc.tx_skb) {
st->l1.requestpull = 0;
st->l1.l1l2(st, PH_PULL_ACK, NULL);
test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
st->l1.l1l2(st, PH_PULL_CNF, NULL);
} else
st->l1.requestpull = !0;
test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
break;
}
}
@ -495,7 +500,7 @@ close_hfcstate(struct BCState *bcs)
struct sk_buff *skb;
mode_hfc(bcs, 0, 0);
if (bcs->Flag & BC_FLG_INIT) {
if (test_bit(BC_FLG_INIT, &bcs->Flag)) {
while ((skb = skb_dequeue(&bcs->rqueue))) {
dev_kfree_skb(skb, FREE_READ);
}
@ -505,10 +510,10 @@ close_hfcstate(struct BCState *bcs)
if (bcs->hw.hfc.tx_skb) {
dev_kfree_skb(bcs->hw.hfc.tx_skb, FREE_WRITE);
bcs->hw.hfc.tx_skb = NULL;
bcs->Flag &= ~BC_FLG_BUSY;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
}
}
bcs->Flag &= ~BC_FLG_INIT;
test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
}
static int
@ -517,13 +522,12 @@ open_hfcstate(struct IsdnCardState *cs,
{
struct BCState *bcs = cs->bcs + bc;
if (!(bcs->Flag & BC_FLG_INIT)) {
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
skb_queue_head_init(&bcs->rqueue);
skb_queue_head_init(&bcs->squeue);
}
bcs->Flag |= BC_FLG_INIT;
bcs->hw.hfc.tx_skb = NULL;
bcs->Flag &= ~BC_FLG_BUSY;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->event = 0;
bcs->tx_cnt = 0;
return (0);
@ -534,15 +538,15 @@ hfc_manl1(struct PStack *st, int pr,
void *arg)
{
switch (pr) {
case (PH_ACTIVATE):
st->l1.bcs->Flag |= BC_FLG_ACTIV;
case (PH_ACTIVATE_REQ):
test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
mode_hfc(st->l1.bcs, st->l1.mode, st->l1.bc);
st->l1.l1man(st, PH_ACTIVATE, NULL);
st->l1.l1man(st, PH_ACTIVATE_CNF, NULL);
break;
case (PH_DEACTIVATE):
if (!(st->l1.bcs->Flag & BC_FLG_BUSY))
case (PH_DEACTIVATE_REQ):
if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag))
mode_hfc(st->l1.bcs, 0, 0);
st->l1.bcs->Flag &= ~BC_FLG_ACTIV;
test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
break;
}
}
@ -556,8 +560,6 @@ setstack_hfc(struct PStack *st, struct BCState *bcs)
st->l2.l2l1 = hfc_l2l1;
st->ma.manl1 = hfc_manl1;
setstack_manager(st);
st->l1.act_state = 0;
st->l1.requestpull = 0;
bcs->st = st;
return (0);
}

View File

@ -6,6 +6,9 @@
*
*
* $Log$
* Revision 1.3 1997/07/27 21:38:34 keil
* new B-channel interface
*
* Revision 1.2 1997/06/26 11:16:17 keil
* first version
*
@ -61,14 +64,14 @@ modehscx(struct BCState *bcs, int mode, int bc)
cs->BC_Write_Reg(cs, hscx, HSCX_RCCR, 7);
/* Switch IOM 1 SSI */
if ((cs->HW_Flags & HW_IOM1) && (hscx == 0))
if (test_bit(HW_IOM1, &cs->HW_Flags) && (hscx == 0))
bc = 1 - bc;
if (bc == 0) {
cs->BC_Write_Reg(cs, hscx, HSCX_TSAX,
(cs->HW_Flags & HW_IOM1) ? 0x7 : 0x2f);
test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : 0x2f);
cs->BC_Write_Reg(cs, hscx, HSCX_TSAR,
(cs->HW_Flags & HW_IOM1) ? 0x7 : 0x2f);
test_bit(HW_IOM1, &cs->HW_Flags) ? 0x7 : 0x2f);
} else {
cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, 0x3);
cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, 0x3);
@ -106,7 +109,7 @@ hscx_l2l1(struct PStack *st, int pr, void *arg)
long flags;
switch (pr) {
case (PH_DATA):
case (PH_DATA_REQ):
save_flags(flags);
cli();
if (st->l1.bcs->hw.hscx.tx_skb) {
@ -114,28 +117,28 @@ hscx_l2l1(struct PStack *st, int pr, void *arg)
restore_flags(flags);
} else {
st->l1.bcs->hw.hscx.tx_skb = skb;
st->l1.bcs->Flag |= BC_FLG_BUSY;
test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
st->l1.bcs->hw.hscx.count = 0;
restore_flags(flags);
st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
}
break;
case (PH_DATA_PULLED):
case (PH_PULL_IND):
if (st->l1.bcs->hw.hscx.tx_skb) {
printk(KERN_WARNING "hscx_l2l1: this shouldn't happen\n");
break;
}
st->l1.bcs->Flag |= BC_FLG_BUSY;
test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
st->l1.bcs->hw.hscx.tx_skb = skb;
st->l1.bcs->hw.hscx.count = 0;
st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
break;
case (PH_REQUEST_PULL):
case (PH_PULL_REQ):
if (!st->l1.bcs->hw.hscx.tx_skb) {
st->l1.requestpull = 0;
st->l1.l1l2(st, PH_PULL_ACK, NULL);
test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
st->l1.l1l2(st, PH_PULL_CNF, NULL);
} else
st->l1.requestpull = !0;
test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
break;
}
@ -147,7 +150,7 @@ close_hscxstate(struct BCState *bcs)
struct sk_buff *skb;
modehscx(bcs, 0, 0);
if (bcs->Flag & BC_FLG_INIT) {
if (test_bit(BC_FLG_INIT, &bcs->Flag)) {
if (bcs->hw.hscx.rcvbuf) {
kfree(bcs->hw.hscx.rcvbuf);
bcs->hw.hscx.rcvbuf = NULL;
@ -161,10 +164,10 @@ close_hscxstate(struct BCState *bcs)
if (bcs->hw.hscx.tx_skb) {
dev_kfree_skb(bcs->hw.hscx.tx_skb, FREE_WRITE);
bcs->hw.hscx.tx_skb = NULL;
bcs->Flag &= ~BC_FLG_BUSY;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
}
}
bcs->Flag &= ~BC_FLG_INIT;
test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
}
static int
@ -173,7 +176,7 @@ open_hscxstate(struct IsdnCardState *cs,
{
struct BCState *bcs = cs->bcs + bc;
if (!(bcs->Flag & BC_FLG_INIT)) {
if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for hscx.rcvbuf\n");
@ -182,9 +185,8 @@ open_hscxstate(struct IsdnCardState *cs,
skb_queue_head_init(&bcs->rqueue);
skb_queue_head_init(&bcs->squeue);
}
bcs->Flag |= BC_FLG_INIT;
bcs->hw.hscx.tx_skb = NULL;
bcs->Flag &= ~BC_FLG_BUSY;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
bcs->event = 0;
bcs->hw.hscx.rcvidx = 0;
bcs->tx_cnt = 0;
@ -196,15 +198,15 @@ hscx_manl1(struct PStack *st, int pr,
void *arg)
{
switch (pr) {
case (PH_ACTIVATE):
st->l1.bcs->Flag |= BC_FLG_ACTIV;
case (PH_ACTIVATE_REQ):
test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
modehscx(st->l1.bcs, st->l1.mode, st->l1.bc);
st->l1.l1man(st, PH_ACTIVATE, NULL);
st->l1.l1man(st, PH_ACTIVATE_CNF, NULL);
break;
case (PH_DEACTIVATE):
if (!(st->l1.bcs->Flag & BC_FLG_BUSY))
case (PH_DEACTIVATE_REQ):
if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag))
modehscx(st->l1.bcs, 0, 0);
st->l1.bcs->Flag &= ~BC_FLG_ACTIV;
test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
break;
}
}
@ -218,8 +220,6 @@ setstack_hscx(struct PStack *st, struct BCState *bcs)
st->l2.l2l1 = hscx_l2l1;
st->ma.manl1 = hscx_manl1;
setstack_manager(st);
st->l1.act_state = 0;
st->l1.requestpull = 0;
bcs->st = st;
return (0);
}

View File

@ -7,6 +7,11 @@
* This is an include file for fast inline IRQ stuff
*
* $Log$
* Revision 1.5 1997/10/01 09:21:35 fritz
* Removed old compatibility stuff for 2.0.X kernels.
* From now on, this code is for 2.1.X ONLY!
* Old stuff is still in the separate branch.
*
* Revision 1.4 1997/08/15 17:48:02 keil
* cosmetic
*
@ -86,7 +91,7 @@ hscx_empty_fifo(struct BCState *bcs, int count)
WriteHSCXCMDR(cs, bcs->channel, 0x80);
restore_flags(flags);
if (cs->debug & L1_DEB_HSCX_FIFO) {
char tmp[128];
char tmp[256];
char *t = tmp;
t += sprintf(t, "hscx_empty_fifo %c cnt %d",
@ -101,6 +106,7 @@ hscx_fill_fifo(struct BCState *bcs)
{
struct IsdnCardState *cs = bcs->cs;
int more, count;
int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
u_char *ptr;
long flags;
@ -114,9 +120,9 @@ hscx_fill_fifo(struct BCState *bcs)
return;
more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0;
if (bcs->hw.hscx.tx_skb->len > 32) {
if (bcs->hw.hscx.tx_skb->len > fifo_size) {
more = !0;
count = 32;
count = fifo_size;
} else
count = bcs->hw.hscx.tx_skb->len;
@ -131,7 +137,7 @@ hscx_fill_fifo(struct BCState *bcs)
WriteHSCXCMDR(cs, bcs->channel, more ? 0x8 : 0xa);
restore_flags(flags);
if (cs->debug & L1_DEB_HSCX_FIFO) {
char tmp[128];
char tmp[256];
char *t = tmp;
t += sprintf(t, "hscx_fill_fifo %c cnt %d",
@ -147,10 +153,11 @@ hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
u_char r;
struct BCState *bcs = cs->bcs + hscx;
struct sk_buff *skb;
int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
int count;
char tmp[32];
if (!(bcs->Flag & BC_FLG_INIT))
if (!test_bit(BC_FLG_INIT, &bcs->Flag))
return;
if (val & 0x80) { /* RME */
@ -170,9 +177,10 @@ hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
debugl1(cs, "HSCX CRC error");
WriteHSCXCMDR(cs, hscx, 0x80);
} else {
count = READHSCX(cs, hscx, HSCX_RBCL) & 0x1f;
count = READHSCX(cs, hscx, HSCX_RBCL) & (
test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f);
if (count == 0)
count = 32;
count = fifo_size;
hscx_empty_fifo(bcs, count);
if ((count = bcs->hw.hscx.rcvidx - 1) > 0) {
if (cs->debug & L1_DEB_HSCX_FIFO) {
@ -191,13 +199,13 @@ hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
hscx_sched_event(bcs, B_RCVBUFREADY);
}
if (val & 0x40) { /* RPF */
hscx_empty_fifo(bcs, 32);
hscx_empty_fifo(bcs, fifo_size);
if (bcs->mode == L1_MODE_TRANS) {
/* receive audio data */
if (!(skb = dev_alloc_skb(32)))
if (!(skb = dev_alloc_skb(fifo_size)))
printk(KERN_WARNING "HiSax: receive out of memory\n");
else {
memcpy(skb_put(skb, 32), bcs->hw.hscx.rcvbuf, 32);
memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size);
skb_queue_tail(&bcs->rqueue, skb);
}
bcs->hw.hscx.rcvidx = 0;
@ -210,18 +218,19 @@ hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
hscx_fill_fifo(bcs);
return;
} else {
if (bcs->st->lli.l1writewakeup &&
(PACKET_NOACK != bcs->hw.hscx.tx_skb->pkt_type))
bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count);
dev_kfree_skb(bcs->hw.hscx.tx_skb, FREE_WRITE);
bcs->hw.hscx.count = 0;
if (bcs->st->lli.l1writewakeup)
bcs->st->lli.l1writewakeup(bcs->st);
bcs->hw.hscx.count = 0;
bcs->hw.hscx.tx_skb = NULL;
}
if ((bcs->hw.hscx.tx_skb = skb_dequeue(&bcs->squeue))) {
bcs->hw.hscx.count = 0;
bcs->Flag |= BC_FLG_BUSY;
test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
hscx_fill_fifo(bcs);
} else {
bcs->Flag &= ~BC_FLG_BUSY;
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
hscx_sched_event(bcs, B_XMTBUFREADY);
}
}

View File

@ -1,25 +1,15 @@
/* $Id$
* $Log$
* Revision 2.2 1997/07/30 17:11:09 keil
* L1deactivated exported
*
* Revision 2.1 1997/07/27 21:43:58 keil
* new l1 interface
*
* Revision 2.0 1997/06/26 11:02:55 keil
* New Layer and card interface
*
* Revision 1.4 1997/04/06 22:55:52 keil
* Using SKB's
*
* Revision 1.3 1996/12/08 19:41:55 keil
* L2FRAME_DEBUG
*
* Revision 1.2 1996/10/27 22:26:27 keil
* ISAC/HSCX version functions
*
* Revision 1.1 1996/10/13 20:03:47 keil
* Initial revision
*
*
*
*/
@ -35,20 +25,25 @@
#define L1_DEB_HSCX 0x10
#define L1_DEB_HSCX_FIFO 0x20
#define L1_DEB_LAPD 0x40
#define L1_DEB_IPAC 0x80
#define D_RCVBUFREADY 0
#define D_XMTBUFREADY 1
#define L1_PH_ACT 2
#define L1_PH_DEACT 3
#define D_L1STATECHANGE 2
#define D_CLEARBUSY 3
#define D_RX_MON0 4
#define D_RX_MON1 5
#define D_TX_MON0 6
#define D_TX_MON1 7
#define B_RCVBUFREADY 0
#define B_XMTBUFREADY 1
extern void debugl1(struct IsdnCardState *sp, char *msg);
extern get_irq(int cardnr, void *routine);
extern void L1activated(struct IsdnCardState *cs);
extern void L1deactivated(struct IsdnCardState *cs);
extern int L1act_wanted(struct IsdnCardState *cs);
extern void DChannel_proc_xmt(struct IsdnCardState *cs);
extern void DChannel_proc_rcv(struct IsdnCardState *cs);
#ifdef L2FRAME_DEBUG

View File

@ -7,6 +7,11 @@
* Fritz Elfert
*
* $Log$
* Revision 2.2 1997/10/01 09:21:41 fritz
* Removed old compatibility stuff for 2.0.X kernels.
* From now on, this code is for 2.1.X ONLY!
* Old stuff is still in the separate branch.
*
* Revision 2.1 1997/08/03 14:36:32 keil
* Implement RESTART procedure
*
@ -202,8 +207,7 @@ extern void setstack_1tr6(struct PStack *st);
#endif
struct l3_process
*
getl3proc(struct PStack *st, int cr)
*getl3proc(struct PStack *st, int cr)
{
struct l3_process *p = st->l3.proc;
@ -214,9 +218,9 @@ getl3proc(struct PStack *st, int cr)
p = p->next;
return (NULL);
}
struct l3_process
*
new_l3_process(struct PStack *st, int cr)
*new_l3_process(struct PStack *st, int cr)
{
struct l3_process *p, *np;
@ -236,6 +240,7 @@ new_l3_process(struct PStack *st, int cr)
p->debug = L3_DEB_WARN;
p->callref = cr;
p->state = 0;
p->chan = NULL;
p->st = st;
p->N303 = st->l3.N303;
L3InitTimer(p, &p->timer);

View File

@ -6,6 +6,9 @@
*
*
* $Log$
* Revision 2.1 1997/08/03 15:28:09 keil
* release L3 empty processes
*
* Revision 2.0 1997/07/27 21:15:45 keil
* New Callref based layer3
*
@ -47,6 +50,65 @@ l3_1TR6_message(struct l3_process *pc, u_char mt, u_char pd)
pc->st->l3.l3l2(pc->st, DL_DATA, skb);
}
static int
l31tr6_check_messagetype_validity(int mt, int pd) {
/* verify if a message type exists */
if (pd == PROTO_DIS_N0)
switch(mt) {
case MT_N0_REG_IND:
case MT_N0_CANC_IND:
case MT_N0_FAC_STA:
case MT_N0_STA_ACK:
case MT_N0_STA_REJ:
case MT_N0_FAC_INF:
case MT_N0_INF_ACK:
case MT_N0_INF_REJ:
case MT_N0_CLOSE:
case MT_N0_CLO_ACK:
return(1);
default:
return(0);
}
else if (pd == PROTO_DIS_N1)
switch(mt) {
case MT_N1_ESC:
case MT_N1_ALERT:
case MT_N1_CALL_SENT:
case MT_N1_CONN:
case MT_N1_CONN_ACK:
case MT_N1_SETUP:
case MT_N1_SETUP_ACK:
case MT_N1_RES:
case MT_N1_RES_ACK:
case MT_N1_RES_REJ:
case MT_N1_SUSP:
case MT_N1_SUSP_ACK:
case MT_N1_SUSP_REJ:
case MT_N1_USER_INFO:
case MT_N1_DET:
case MT_N1_DISC:
case MT_N1_REL:
case MT_N1_REL_ACK:
case MT_N1_CANC_ACK:
case MT_N1_CANC_REJ:
case MT_N1_CON_CON:
case MT_N1_FAC:
case MT_N1_FAC_ACK:
case MT_N1_FAC_CAN:
case MT_N1_FAC_REG:
case MT_N1_FAC_REJ:
case MT_N1_INFO:
case MT_N1_REG_ACK:
case MT_N1_REG_REJ:
case MT_N1_STAT:
return (1);
default:
return(0);
}
return(0);
}
static void
l3_1tr6_setup_req(struct l3_process *pc, u_char pr, void *arg)
{
@ -661,9 +723,17 @@ up1tr6(struct PStack *st, int pr, void *arg)
struct sk_buff *skb = arg;
char tmp[80];
if (skb->len < 4) {
if (st->l3.debug & L3_DEB_PROTERR) {
sprintf(tmp, "up1tr6 len only %d", skb->len);
l3_debug(st, tmp);
}
dev_kfree_skb(skb, FREE_READ);
return;
}
if ((skb->data[0] & 0xfe) != PROTO_DIS_N0) {
if (st->l3.debug & L3_DEB_PROTERR) {
sprintf(tmp, "up1tr6%sunexpected discriminator %x message len %ld",
sprintf(tmp, "up1tr6%sunexpected discriminator %x message len %d",
(pr == DL_DATA) ? " " : "(broadcast) ",
skb->data[0], skb->len);
l3_debug(st, tmp);
@ -671,8 +741,16 @@ up1tr6(struct PStack *st, int pr, void *arg)
dev_kfree_skb(skb, FREE_READ);
return;
}
cr = getcallref(skb->data);
mt = skb->data[skb->data[1] + 2];
if (skb->data[1] != 1) {
if (st->l3.debug & L3_DEB_PROTERR) {
sprintf(tmp, "up1tr6 CR len not 1");
l3_debug(st, tmp);
}
dev_kfree_skb(skb, FREE_READ);
return;
}
cr = skb->data[2];
mt = skb->data[3];
if (skb->data[0] == PROTO_DIS_N0) {
dev_kfree_skb(skb, FREE_READ);
if (st->l3.debug & L3_DEB_STATE) {
@ -682,8 +760,12 @@ up1tr6(struct PStack *st, int pr, void *arg)
}
} else if (skb->data[0] == PROTO_DIS_N1) {
if (!(proc = getl3proc(st, cr))) {
if (mt == MT_N1_SETUP) {
if ((mt == MT_N1_SETUP) && (cr < 128)) {
if (!(proc = new_l3_process(st, cr))) {
if (st->l3.debug & L3_DEB_PROTERR) {
sprintf(tmp, "up1tr6 no roc mem");
l3_debug(st, tmp);
}
dev_kfree_skb(skb, FREE_READ);
return;
}

View File

@ -9,6 +9,9 @@
* Fritz Elfert
*
* $Log$
* Revision 2.2 1997/08/07 17:44:36 keil
* Fix RESTART
*
* Revision 2.1 1997/08/03 14:36:33 keil
* Implement RESTART procedure
*
@ -40,6 +43,44 @@ const char *dss1_revision = "$Revision$";
*ptr++ = cref^0x80; \
*ptr++ = mty
static int
l3dss1_check_messagetype_validity(int mt) {
/* verify if a message type exists */
switch(mt) {
case MT_ALERTING:
case MT_CALL_PROCEEDING:
case MT_CONNECT:
case MT_CONNECT_ACKNOWLEDGE:
case MT_PROGRESS:
case MT_SETUP:
case MT_SETUP_ACKNOWLEDGE:
case MT_RESUME:
case MT_RESUME_ACKNOWLEDGE:
case MT_RESUME_REJECT:
case MT_SUSPEND:
case MT_SUSPEND_ACKNOWLEDGE:
case MT_SUSPEND_REJECT:
case MT_USER_INFORMATION:
case MT_DISCONNECT:
case MT_RELEASE:
case MT_RELEASE_COMPLETE:
case MT_RESTART:
case MT_RESTART_ACKNOWLEDGE:
case MT_SEGMENT:
case MT_CONGESTION_CONTROL:
case MT_INFORMATION:
case MT_FACILITY:
case MT_NOTIFY:
case MT_STATUS:
case MT_STATUS_ENQUIRY:
return(1);
default:
return(0);
}
return(0);
}
static void
l3dss1_message(struct l3_process *pc, u_char mt)
{
@ -96,6 +137,8 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
u_char screen = 0x80;
u_char *teln;
u_char *msn;
u_char *sub;
u_char *sp;
int l;
MsgHead(p, pc->callref, MT_SETUP);
@ -159,6 +202,15 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
*p++ = channel;
}
msn = pc->para.setup.eazmsn;
sub = NULL;
sp = msn;
while (*sp) {
if ('.' == *sp) {
sub = sp;
*sp = 0;
} else
sp++;
}
if (*msn) {
*p++ = 0x6c;
*p++ = strlen(msn) + (screen ? 2 : 1);
@ -171,14 +223,41 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
while (*msn)
*p++ = *msn++ & 0x7f;
}
if (sub) {
*sub++ = '.';
*p++ = 0x6d; /* Calling party subaddress */
*p++ = strlen(sub) + 2;
*p++ = 0x80; /* NSAP coded */
*p++ = 0x50; /* local IDI format */
while (*sub)
*p++ = *sub++ & 0x7f;
}
sub = NULL;
sp = teln;
while (*sp) {
if ('.' == *sp) {
sub = sp;
*sp = 0;
} else
sp++;
}
*p++ = 0x70;
*p++ = strlen(teln) + 1;
/* Classify as AnyPref. */
*p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
while (*teln)
*p++ = *teln++ & 0x7f;
if (sub) {
*sub++ = '.';
*p++ = 0x71; /* Called party subaddress */
*p++ = strlen(sub) + 2;
*p++ = 0x80; /* NSAP coded */
*p++ = 0x50; /* local IDI format */
while (*sub)
*p++ = *sub++ & 0x7f;
}
l = p - tmp;
if (!(skb = l3_alloc_skb(l)))
return;
@ -273,15 +352,74 @@ l3dss1_alerting(struct l3_process *pc, u_char pr, void *arg)
pc->st->l3.l3l4(pc, CC_ALERTING_IND, NULL);
}
static void
l3dss1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg)
{
/* This routine is called if here was no SETUP made (checks in dss1up and in
* l3dss1_setup) and a RELEASE_COMPLETE have to be sent with an error code
* It is called after it is veryfied that Layer2 is up.
* The cause value is allready in pc->para.cause
* MT_STATUS_ENQUIRE in the NULL state is handled too
*/
u_char tmp[16];
u_char *p=tmp;
int l;
struct sk_buff *skb;
switch (pc->para.cause) {
case 81: /* 0x51 invalid callreference */
case 96: /* 0x60 mandory IE missing */
case 101: /* 0x65 incompatible Callstate */
MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
*p++ = IE_CAUSE;
*p++ = 0x2;
*p++ = 0x80;
*p++ = pc->para.cause | 0x80;
break;
default:
printk(KERN_ERR "HiSax internal error l3dss1_msg_without_setup\n");
return;
}
l = p - tmp;
if (!(skb = l3_alloc_skb(l)))
return;
memcpy(skb_put(skb, l), tmp, l);
pc->st->l3.l3l2(pc->st, DL_DATA, skb);
release_l3_process(pc);
}
static void
l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
{
u_char *p;
u_char *p, *ptmp[8];
int i;
int bcfound = 0;
char tmp[80];
struct sk_buff *skb = arg;
/* ETS 300-104 1.3.4 and 1.3.5
* we need to detect unknown inform. element from 0 to 7
*/
p = skb->data;
for(i = 0; i < 8; i++)
ptmp[i] = skb->data;
if (findie(ptmp[1], skb->len, 0x01, 0)
|| findie(ptmp[2], skb->len, 0x02, 0)
|| findie(ptmp[3], skb->len, 0x03, 0)
|| findie(ptmp[5], skb->len, 0x05, 0)
|| findie(ptmp[6], skb->len, 0x06, 0)
|| findie(ptmp[7], skb->len, 0x07, 0)) {
/* if ie is < 8 and not 0 nor 4, send RELEASE_COMPLETE
* cause 0x60
*/
pc->para.cause = 0x60;
dev_kfree_skb(skb, FREE_READ);
if (pc->state == 0)
pc->st->l3.l3l4(pc, CC_ESTABLISH, NULL);
else
l3dss1_msg_without_setup(pc, pr, NULL);
return;
}
/*
* Channel Identification
@ -328,8 +466,18 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
default:
pc->para.setup.si1 = 0;
}
} else if (pc->debug & L3_DEB_WARN)
l3_debug(pc->st, "setup without bearer capabilities");
} else {
if (pc->debug & L3_DEB_WARN)
l3_debug(pc->st, "setup without bearer capabilities");
/* ETS 300-104 1.3.3 */
pc->para.cause = 0x60;
dev_kfree_skb(skb, FREE_READ);
if (pc->state == 0)
pc->st->l3.l3l4(pc, CC_ESTABLISH, NULL);
else
l3dss1_msg_without_setup(pc, pr, NULL);
return;
}
p = skb->data;
if ((p = findie(p, skb->len, 0x70, 0)))
@ -337,6 +485,16 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
else
pc->para.setup.eazmsn[0] = 0;
p = skb->data;
if ((p = findie(p, skb->len, 0x71, 0))) {
/* Called party subaddress */
if ((p[1]>=2) && (p[2]==0x80) && (p[3]==0x50)) {
tmp[0]='.';
iecpy(&tmp[1], p, 2);
strcat(pc->para.setup.eazmsn, tmp);
} else if (pc->debug & L3_DEB_WARN)
l3_debug(pc->st, "wrong called subaddress");
}
p = skb->data;
if ((p = findie(p, skb->len, 0x6c, 0))) {
pc->para.setup.plan = p[2];
@ -352,13 +510,23 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
pc->para.setup.plan = 0;
pc->para.setup.screen = 0;
}
p = skb->data;
if ((p = findie(p, skb->len, 0x6d, 0))) {
/* Calling party subaddress */
if ((p[1]>=2) && (p[2]==0x80) && (p[3]==0x50)) {
tmp[0]='.';
iecpy(&tmp[1], p, 2);
strcat(pc->para.setup.phone, tmp);
} else if (pc->debug & L3_DEB_WARN)
l3_debug(pc->st, "wrong calling subaddress");
}
dev_kfree_skb(skb, FREE_READ);
if (bcfound) {
if ((pc->para.setup.si1 != 7) && (pc->debug & L3_DEB_WARN)) {
sprintf(tmp, "non-digital call: %s -> %s",
pc->para.setup.phone,
pc->para.setup.eazmsn);
pc->para.setup.phone, pc->para.setup.eazmsn);
l3_debug(pc->st, tmp);
}
newl3state(pc, 6);
@ -512,6 +680,61 @@ l3dss1_status_enq(struct l3_process *pc, u_char pr, void *arg)
pc->st->l3.l3l2(pc->st, DL_DATA, skb);
}
static void
l3dss1_status_req(struct l3_process *pc, u_char pr, void *arg)
{
/* ETS 300-104 7.4.1, 8.4.1, 10.3.1, 11.4.1, 12.4.1, 13.4.1, 14.4.1...
if setup has been made and a non expected message type is received, we must send MT_STATUS cause 0x62 */
u_char tmp[16];
u_char *p = tmp;
int l;
struct sk_buff *skb = arg;
dev_kfree_skb(skb, FREE_READ);
MsgHead(p, pc->callref, MT_STATUS);
*p++ = IE_CAUSE;
*p++ = 0x2;
*p++ = 0x80;
*p++ = 0x62 | 0x80; /* status sending */
*p++ = 0x14; /* CallState */
*p++ = 0x1;
*p++ = pc->state & 0x3f;
l = p - tmp;
if (!(skb = l3_alloc_skb(l)))
return;
memcpy(skb_put(skb, l), tmp, l);
pc->st->l3.l3l2(pc->st, DL_DATA, skb);
}
static void
l3dss1_release_ind(struct l3_process *pc, u_char pr, void *arg)
{
u_char *p;
struct sk_buff *skb = arg;
int callState = 0;
p = skb->data;
if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) {
p++;
if (1== *p++)
callState = *p;
}
if(callState == 0) {
/* ETS 300-104 7.6.1, 8.6.1, 10.6.1... and 16.1
* set down layer 3 without sending any message
*/
pc->st->l3.l3l4(pc, CC_RELEASE_IND, NULL);
newl3state(pc, 0);
release_l3_process(pc);
} else {
pc->st->l3.l3l4(pc, CC_IGNORE, NULL);
}
}
static void
l3dss1_t303(struct l3_process *pc, u_char pr, void *arg)
{
@ -547,7 +770,7 @@ l3dss1_t305(struct l3_process *pc, u_char pr, void *arg)
L3DelTimer(&pc->timer);
if (pc->para.cause > 0)
cause = pc->para.cause;
cause = pc->para.cause | 0x80;
MsgHead(p, pc->callref, MT_RELEASE);
@ -615,15 +838,19 @@ l3dss1_status(struct l3_process *pc, u_char pr, void *arg)
char tmp[64], *t;
int l;
struct sk_buff *skb = arg;
int cause, callState;
cause = callState = -1;
p = skb->data;
t = tmp;
if ((p = findie(p, skb->len, IE_CAUSE, 0))) {
p++;
l = *p++;
t += sprintf(t,"Status CR %x Cause:", pc->callref);
while (l--)
while (l--) {
cause = *p;
t += sprintf(t," %2x",*p++);
}
} else
sprintf(t,"Status CR %x no Cause", pc->callref);
l3_debug(pc->st, tmp);
@ -632,14 +859,23 @@ l3dss1_status(struct l3_process *pc, u_char pr, void *arg)
t += sprintf(t,"Status state %x ", pc->state);
if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) {
p++;
if (1== *p++)
if (1== *p++) {
callState = *p;
t += sprintf(t,"peer state %x" , *p);
}
else
t += sprintf(t,"peer state len error");
} else
sprintf(t,"no peer state");
l3_debug(pc->st, tmp);
dev_kfree_skb(skb, FREE_READ);
if(((cause & 0x7f) == 0x6f) && (callState == 0)) {
/* ETS 300-104 7.6.1, 8.6.1, 10.6.1...
* if received MT_STATUS with cause == 0x6f and call
* state == 0, then we must set down layer 3
*/
l3dss1_release_ind(pc, pr, arg);
} else
dev_kfree_skb(skb, FREE_READ);
}
static void
@ -700,6 +936,8 @@ l3dss1_global_restart(struct l3_process *pc, u_char pr, void *arg)
/* *INDENT-OFF* */
static struct stateentry downstatelist[] =
{
{SBIT(0),
CC_ESTABLISH, l3dss1_msg_without_setup},
{SBIT(0),
CC_SETUP_REQ, l3dss1_setup_req},
{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(10),
@ -741,28 +979,45 @@ static struct stateentry datastatelist[] =
{
{ALL_STATES,
MT_STATUS_ENQUIRY, l3dss1_status_enq},
{SBIT(19),
MT_STATUS, l3dss1_release_ind},
{ALL_STATES,
MT_STATUS, l3dss1_status},
{SBIT(0) | SBIT(6),
MT_SETUP, l3dss1_setup},
{SBIT(1) | SBIT(2),
MT_CALL_PROCEEDING, l3dss1_call_proc},
{SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
MT_CALL_PROCEEDING, l3dss1_status_req},
{SBIT(1),
MT_SETUP_ACKNOWLEDGE, l3dss1_setup_ack},
{SBIT(2) | SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
MT_SETUP_ACKNOWLEDGE, l3dss1_status_req},
{SBIT(1) | SBIT(2) | SBIT(3),
MT_ALERTING, l3dss1_alerting},
{SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
MT_ALERTING, l3dss1_status_req},
{SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) |
SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19),
MT_RELEASE_COMPLETE, l3dss1_release_cmpl},
{SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) |
SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19),
{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) |
SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) /*| SBIT(19)*/,
MT_RELEASE, l3dss1_release},
{SBIT(19), MT_RELEASE, l3dss1_release_ind},
{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10),
MT_DISCONNECT, l3dss1_disconnect},
{SBIT(11),
MT_DISCONNECT, l3dss1_release_req},
{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4),
MT_CONNECT, l3dss1_connect},
{SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
MT_CONNECT, l3dss1_status_req},
{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(11) | SBIT(19),
MT_CONNECT_ACKNOWLEDGE, l3dss1_status_req},
{SBIT(8),
MT_CONNECT_ACKNOWLEDGE, l3dss1_connect_ack},
{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(8) | SBIT(10) | SBIT(11) | SBIT(19),
MT_INVALID, l3dss1_status_req},
};
static int datasllen = sizeof(datastatelist) / sizeof(struct stateentry);
@ -824,14 +1079,15 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
static void
dss1up(struct PStack *st, int pr, void *arg)
{
int i, mt, cr;
int i, mt, cr, cause, callState;
char *ptr;
struct sk_buff *skb = arg;
struct l3_process *proc;
char tmp[80];
if (skb->data[0] != PROTO_DIS_EURO) {
if (st->l3.debug & L3_DEB_PROTERR) {
sprintf(tmp, "dss1up%sunexpected discriminator %x message len %ld",
sprintf(tmp, "dss1up%sunexpected discriminator %x message len %d",
(pr == DL_DATA) ? " " : "(broadcast) ",
skb->data[0], skb->len);
l3_debug(st, tmp);
@ -848,16 +1104,79 @@ dss1up(struct PStack *st, int pr, void *arg)
dev_kfree_skb(skb, FREE_READ);
return;
} else if (!(proc = getl3proc(st, cr))) {
/* No transaction process exist, that means no call with
* this callreference is active
*/
if (mt == MT_SETUP) {
/* Setup creates a new transaction process */
if (!(proc = new_l3_process(st, cr))) {
/* May be to answer with RELEASE_COMPLETE and
* CAUSE 0x2f "Resource unavailable", but this
* need a new_l3_process too ... arghh
*/
dev_kfree_skb(skb, FREE_READ);
return;
}
} else {
} else if (mt == MT_STATUS) {
cause = 0;
if((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
ptr++;
if (*ptr++ == 2)
ptr++;
cause = *ptr & 0x7f;
}
callState = 0;
if((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {
ptr++;
if (*ptr++ == 2)
ptr++;
callState = *ptr;
}
if (callState == 0) {
/* ETS 300-104 part 2.4.1
* if setup has not been made and a message type
* MT_STATUS is received with call state == 0,
* we must send nothing
*/
dev_kfree_skb(skb, FREE_READ);
return;
} else {
/* ETS 300-104 part 2.4.2
* if setup has not been made and a message type
* MT_STATUS is received with call state != 0,
* we must send MT_RELEASE_COMPLETE cause 101
*/
dev_kfree_skb(skb, FREE_READ);
if ((proc = new_l3_process(st, cr))) {
proc->para.cause = 0x65; /* 101 */
proc->st->l3.l3l4(proc, CC_ESTABLISH, NULL);
}
return;
}
} else if (mt == MT_RELEASE_COMPLETE){
dev_kfree_skb(skb, FREE_READ);
return;
} else {
/* ETS 300-104 part 2
* if setup has not been made and a message type
* (except MT_SETUP and RELEASE_COMPLETE) is received,
* we must send MT_RELEASE_COMPLETE cause 81 */
dev_kfree_skb(skb, FREE_READ);
if ((proc = new_l3_process(st, cr))) {
proc->para.cause = 0x51; /* 81 */
proc->st->l3.l3l4(proc, CC_ESTABLISH, NULL);
}
return;
}
} else if (!l3dss1_check_messagetype_validity(mt)) {
/* ETS 300-104 7.4.2, 8.4.2, 10.3.2, 11.4.2, 12.4.2, 13.4.2,
* 14.4.2...
* if setup has been made and invalid message type is received,
* we must send MT_STATUS cause 0x62
*/
mt = MT_INVALID; /* sorry, not clean, but do the right thing ;-) */
}
for (i = 0; i < datasllen; i++)
if ((mt == datastatelist[i].primitive) &&
((1 << proc->state) & datastatelist[i].state))
@ -894,9 +1213,7 @@ dss1down(struct PStack *st, int pr, void *arg)
chan = arg;
cr = newcallref();
cr |= 0x80;
if (!(proc = new_l3_process(st, cr))) {
return;
} else {
if ((proc = new_l3_process(st, cr))) {
proc->chan = chan;
chan->proc = proc;
proc->para.setup = chan->setup;
@ -905,6 +1222,10 @@ dss1down(struct PStack *st, int pr, void *arg)
} else {
proc = arg;
}
if (!proc) {
printk(KERN_ERR "HiSax internal error dss1down without proc\n");
return;
}
for (i = 0; i < downsllen; i++)
if ((pr == downstatelist[i].primitive) &&
((1 << proc->state) & downstatelist[i].state))

View File

@ -3,6 +3,9 @@
* DSS1 (Euro) D-channel protocol defines
*
* $Log$
* Revision 1.3 1997/08/07 17:44:37 keil
* Fix RESTART
*
* Revision 1.2 1997/08/03 14:36:34 keil
* Implement RESTART procedure
*
@ -52,6 +55,8 @@
#define MT_STATUS 0x7d
#define MT_STATUS_ENQUIRY 0x75
#define MT_INVALID 0xff
#define IE_CAUSE 0x08
#define IE_CALL_STATE 0x14
#define IE_CHANNEL_ID 0x18

View File

@ -7,6 +7,11 @@
* Fritz Elfert
*
* $Log$
* Revision 2.3 1997/10/01 09:21:43 fritz
* Removed old compatibility stuff for 2.0.X kernels.
* From now on, this code is for 2.1.X ONLY!
* Old stuff is still in the separate branch.
*
* Revision 2.2 1997/07/31 19:24:39 keil
* fixed a warning
*
@ -134,7 +139,7 @@ put_tei_msg(struct PStack *st, u_char m_id, unsigned int ri, u_char tei)
bp[2] = ri & 0xff;
bp[3] = m_id;
bp[4] = (tei << 1) | 1;
st->l2.l2l1(st, PH_DATA, skb);
st->l2.l2l1(st, PH_DATA_REQ, skb);
}
static void
@ -179,14 +184,14 @@ tei_id_assign(struct FsmInst *fi, int event, void *arg)
if (ri != ost->ma.ri) {
sprintf(tmp, "possible duplicate assignment tei %d", tei);
st->ma.tei_m.printdebug(&st->ma.tei_m, tmp);
ost->l2.l2tei(ost, MDL_VERIFY, NULL);
ost->l2.l2tei(ost, MDL_ERROR_REQ, NULL);
}
} else if (ri == st->ma.ri) {
FsmDelTimer(&st->ma.t202, 1);
FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
st->ma.manl2(st, MDL_ASSIGN, (void *) (int) tei);
st->ma.manl2(st, MDL_ASSIGN_REQ, (void *) (int) tei);
cs = (struct IsdnCardState *) st->l1.hardware;
cs->cardmsg(cs, MDL_ASSIGN, NULL);
cs->cardmsg(cs, MDL_ASSIGN_REQ, NULL);
}
}
@ -195,7 +200,6 @@ tei_id_denied(struct FsmInst *fi, int event, void *arg)
{
struct PStack *st = fi->userdata;
struct sk_buff *skb = arg;
struct IsdnCardState *cs;
int ri, tei;
char tmp[64];
@ -205,13 +209,6 @@ tei_id_denied(struct FsmInst *fi, int event, void *arg)
sprintf(tmp, "identity denied ri %d tei %d", ri, tei);
st->ma.tei_m.printdebug(&st->ma.tei_m, tmp);
}
if (ri == st->ma.ri) {
FsmDelTimer(&st->ma.t202, 2);
FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
st->ma.manl2(st, MDL_ERROR, 0);
cs = (struct IsdnCardState *) st->l1.hardware;
cs->cardmsg(cs, MDL_REMOVE, NULL);
}
}
static void
@ -251,9 +248,9 @@ tei_id_remove(struct FsmInst *fi, int event, void *arg)
if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) {
FsmDelTimer(&st->ma.t202, 5);
FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
st->ma.manl2(st, MDL_REMOVE, 0);
st->ma.manl2(st, MDL_REMOVE_REQ, 0);
cs = (struct IsdnCardState *) st->l1.hardware;
cs->cardmsg(cs, MDL_REMOVE, NULL);
cs->cardmsg(cs, MDL_REMOVE_REQ, NULL);
}
}
@ -292,9 +289,9 @@ tei_id_req_tout(struct FsmInst *fi, int event, void *arg)
} else {
sprintf(tmp, "assign req failed");
st->ma.tei_m.printdebug(&st->ma.tei_m, tmp);
st->ma.manl2(st, MDL_ERROR, 0);
st->ma.manl2(st, MDL_ERROR_IND, 0);
cs = (struct IsdnCardState *) st->l1.hardware;
cs->cardmsg(cs, MDL_REMOVE, NULL);
cs->cardmsg(cs, MDL_REMOVE_REQ, NULL);
FsmChangeState(fi, ST_TEI_NOP);
}
}
@ -317,9 +314,9 @@ tei_id_ver_tout(struct FsmInst *fi, int event, void *arg)
} else {
sprintf(tmp, "verify req for tei %d failed", st->l2.tei);
st->ma.tei_m.printdebug(&st->ma.tei_m, tmp);
st->ma.manl2(st, MDL_REMOVE, 0);
st->ma.manl2(st, MDL_REMOVE_REQ, 0);
cs = (struct IsdnCardState *) st->l1.hardware;
cs->cardmsg(cs, MDL_REMOVE, NULL);
cs->cardmsg(cs, MDL_REMOVE_REQ, NULL);
FsmChangeState(fi, ST_TEI_NOP);
}
}
@ -331,9 +328,9 @@ tei_l1l2(struct PStack *st, int pr, void *arg)
int mt;
char tmp[64];
if (pr == PH_DATA) {
if (pr == PH_DATA_IND) {
if (skb->len < 3) {
sprintf(tmp, "short mgr frame %ld/3", skb->len);
sprintf(tmp, "short mgr frame %d/3", skb->len);
st->ma.tei_m.printdebug(&st->ma.tei_m, tmp);
} else if (((skb->data[0] >> 2) != TEI_SAPI) ||
((skb->data[1] >> 1) != GROUP_TEI)) {
@ -347,7 +344,7 @@ tei_l1l2(struct PStack *st, int pr, void *arg)
} else {
skb_pull(skb, 3);
if (skb->len < 5) {
sprintf(tmp, "short mgr frame %ld/5", skb->len);
sprintf(tmp, "short mgr frame %d/5", skb->len);
st->ma.tei_m.printdebug(&st->ma.tei_m, tmp);
} else if (skb->data[0] != TEI_ENTITY_ID) {
/* wrong management entity identifier, ignore */
@ -382,7 +379,7 @@ static void
tei_l2tei(struct PStack *st, int pr, void *arg)
{
switch (pr) {
case (MDL_ASSIGN):
case (MDL_ASSIGN_IND):
#ifdef TEI_FIXED
if (st->ma.debug) {
char tmp[64];
@ -394,7 +391,7 @@ tei_l2tei(struct PStack *st, int pr, void *arg)
FsmEvent(&st->ma.tei_m, EV_IDREQ, arg);
#endif
break;
case (MDL_VERIFY):
case (MDL_ERROR_REQ):
FsmEvent(&st->ma.tei_m, EV_VERIFY, arg);
break;
default: