patch-2.3.14 linux/drivers/isdn/hisax/l3_1tr6.c
Next file: linux/drivers/isdn/hisax/l3dss1.c
Previous file: linux/drivers/isdn/hisax/jade_irq.c
Back to the patch index
Back to the overall index
- Lines: 368
- Date:
Thu Aug 12 09:42:33 1999
- Orig file:
v2.3.13/linux/drivers/isdn/hisax/l3_1tr6.c
- Orig date:
Sun May 23 10:03:41 1999
diff -u --recursive --new-file v2.3.13/linux/drivers/isdn/hisax/l3_1tr6.c linux/drivers/isdn/hisax/l3_1tr6.c
@@ -1,4 +1,4 @@
-/* $Id: l3_1tr6.c,v 2.8 1998/11/15 23:55:08 keil Exp $
+/* $Id: l3_1tr6.c,v 2.9 1999/07/01 08:11:55 keil Exp $
* German 1TR6 D-channel protocol
*
@@ -10,6 +10,9 @@
*
*
* $Log: l3_1tr6.c,v $
+ * Revision 2.9 1999/07/01 08:11:55 keil
+ * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel
+ *
* Revision 2.8 1998/11/15 23:55:08 keil
* changes from 2.0
*
@@ -56,7 +59,7 @@
#include <linux/ctype.h>
extern char *HiSax_getrev(const char *revision);
-const char *l3_1tr6_revision = "$Revision: 2.8 $";
+const char *l3_1tr6_revision = "$Revision: 2.9 $";
#define MsgHead(ptr, cref, mty, dis) \
*ptr++ = dis; \
@@ -91,14 +94,14 @@
{
struct sk_buff *skb = arg;
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
l3_1tr6_release_req(pc, 0, NULL);
}
static void
l3_1tr6_error(struct l3_process *pc, u_char *msg, struct sk_buff *skb)
{
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
if (pc->st->l3.debug & L3_DEB_WARN)
l3_debug(pc->st, msg);
l3_1tr6_release_req(pc, 0, NULL);
@@ -248,7 +251,7 @@
if ((FAC_SPV == p[3]) || (FAC_Activate == p[3]))
pc->para.spv = 1;
}
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
/* Signal all services, linklevel takes care of Service-Indicator */
if (bcfound) {
@@ -287,7 +290,7 @@
l3_1tr6_error(pc, "missing setup_ack WE0_chanID", skb);
return;
}
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
L3AddTimer(&pc->timer, T304, CC_T304);
pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);
}
@@ -318,7 +321,7 @@
l3_1tr6_error(pc, "missing call sent WE0_chanID", skb);
return;
}
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
L3AddTimer(&pc->timer, T310, CC_T310);
newl3state(pc, 3);
pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc);
@@ -329,7 +332,7 @@
{
struct sk_buff *skb = arg;
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
L3DelTimer(&pc->timer); /* T304 */
newl3state(pc, 4);
pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc);
@@ -360,7 +363,7 @@
}
} else if (pc->st->l3.debug & L3_DEB_CHARGE)
l3_debug(pc->st, "charging info not found");
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
}
@@ -369,7 +372,7 @@
{
struct sk_buff *skb = arg;
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
}
static void
@@ -383,7 +386,7 @@
return;
}
newl3state(pc, 10);
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
pc->para.chargeinfo = 0;
pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc);
}
@@ -407,11 +410,11 @@
pc->para.loc = 0;
}
} else {
- pc->para.cause = -1;
+ pc->para.cause = NO_CAUSE;
l3_1tr6_error(pc, "missing REL cause", skb);
return;
}
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
StopAllL3Timer(pc);
newl3state(pc, 0);
l3_1TR6_message(pc, MT_N1_REL_ACK, PROTO_DIS_N1);
@@ -424,10 +427,10 @@
{
struct sk_buff *skb = arg;
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
StopAllL3Timer(pc);
newl3state(pc, 0);
- pc->para.cause = -1;
+ pc->para.cause = NO_CAUSE;
pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc);
release_l3_process(pc);
}
@@ -475,13 +478,13 @@
} else {
if (pc->st->l3.debug & L3_DEB_WARN)
l3_debug(pc->st, "cause not found");
- pc->para.cause = -1;
+ pc->para.cause = NO_CAUSE;
}
if (!findie(skb->data, skb->len, WE6_date, 6)) {
l3_1tr6_error(pc, "missing connack date", skb);
return;
}
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
newl3state(pc, 12);
pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc);
}
@@ -496,7 +499,7 @@
l3_1tr6_error(pc, "missing connack date", skb);
return;
}
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
newl3state(pc, 10);
pc->para.chargeinfo = 0;
L3DelTimer(&pc->timer);
@@ -567,6 +570,9 @@
case 0x10:
clen = 0;
break;
+ case 0x11:
+ cause = CAUSE_UserBusy;
+ break;
case 0x15:
cause = CAUSE_CallRejected;
break;
@@ -620,7 +626,7 @@
u_char clen = 1;
L3DelTimer(&pc->timer);
- if (pc->para.cause > 0)
+ if (pc->para.cause != NO_CAUSE)
cause = pc->para.cause;
/* Map DSS1 causes */
switch (cause & 0x7f) {
@@ -679,6 +685,24 @@
pc->st->l3.l3l4(pc->st, CC_RELEASE_ERR, pc);
release_l3_process(pc);
}
+
+static void
+l3_1tr6_dl_reset(struct l3_process *pc, u_char pr, void *arg)
+{
+ pc->para.cause = CAUSE_LocalProcErr;
+ l3_1tr6_disconnect_req(pc, pr, NULL);
+ pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
+}
+
+static void
+l3_1tr6_dl_release(struct l3_process *pc, u_char pr, void *arg)
+{
+ newl3state(pc, 0);
+ pc->para.cause = 0x1b; /* Destination out of order */
+ pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
+ release_l3_process(pc);
+}
+
/* *INDENT-OFF* */
static struct stateentry downstl[] =
{
@@ -689,8 +713,6 @@
CC_DISCONNECT | REQUEST, l3_1tr6_disconnect_req},
{SBIT(12),
CC_RELEASE | REQUEST, l3_1tr6_release_req},
- {ALL_STATES,
- CC_DLRL | REQUEST, l3_1tr6_reset},
{SBIT(6),
CC_IGNORE | REQUEST, l3_1tr6_reset},
{SBIT(6),
@@ -751,11 +773,22 @@
{SBIT(19),
MT_N1_REL_ACK, l3_1tr6_rel_ack}
};
-/* *INDENT-ON* */
#define DATASTLN1_LEN \
(sizeof(datastln1) / sizeof(struct stateentry))
+static struct stateentry manstatelist[] =
+{
+ {SBIT(2),
+ DL_ESTABLISH | INDICATION, l3_1tr6_dl_reset},
+ {ALL_STATES,
+ DL_RELEASE | INDICATION, l3_1tr6_dl_release},
+};
+
+#define MANSLLEN \
+ (sizeof(manstatelist) / sizeof(struct stateentry))
+/* *INDENT-ON* */
+
static void
up1tr6(struct PStack *st, int pr, void *arg)
{
@@ -778,20 +811,20 @@
}
if (skb->len < 4) {
if (st->l3.debug & L3_DEB_PROTERR) {
- sprintf(tmp, "up1tr6 len only %ld", skb->len);
+ sprintf(tmp, "up1tr6 len only %d", skb->len);
l3_debug(st, tmp);
}
- dev_kfree_skb(skb);
+ idev_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 | INDICATION)) ? " " : "(broadcast) ",
skb->data[0], skb->len);
l3_debug(st, tmp);
}
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
return;
}
if (skb->data[1] != 1) {
@@ -799,13 +832,13 @@
sprintf(tmp, "up1tr6 CR len not 1");
l3_debug(st, tmp);
}
- dev_kfree_skb(skb);
+ idev_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);
+ idev_kfree_skb(skb, FREE_READ);
if (st->l3.debug & L3_DEB_STATE) {
sprintf(tmp, "up1tr6%s N0 mt %x unhandled",
(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", mt);
@@ -820,11 +853,11 @@
sprintf(tmp, "up1tr6 no roc mem");
l3_debug(st, tmp);
}
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
return;
}
} else {
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
return;
}
} else if ((mt == MT_N1_REL) || (mt == MT_N1_REL_ACK) ||
@@ -832,7 +865,7 @@
(mt == MT_N1_REG_ACK) || (mt == MT_N1_REG_REJ) ||
(mt == MT_N1_SUSP_ACK) || (mt == MT_N1_RES_REJ) ||
(mt == MT_N1_INFO)) {
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
return;
} else {
if (!(proc = new_l3_process(st, cr))) {
@@ -840,7 +873,7 @@
sprintf(tmp, "up1tr6 no roc mem");
l3_debug(st, tmp);
}
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
return;
}
mt = MT_N1_INVALID;
@@ -851,7 +884,7 @@
((1 << proc->state) & datastln1[i].state))
break;
if (i == DATASTLN1_LEN) {
- dev_kfree_skb(skb);
+ idev_kfree_skb(skb, FREE_READ);
if (st->l3.debug & L3_DEB_STATE) {
sprintf(tmp, "up1tr6%sstate %d mt %x unhandled",
(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
@@ -879,7 +912,7 @@
struct Channel *chan;
char tmp[80];
- if (((DL_ESTABLISH | REQUEST)== pr) || ((DL_RELEASE | REQUEST)== pr)) {
+ if ((DL_ESTABLISH | REQUEST)== pr) {
l3_msg(st, pr, NULL);
return;
} else if ((CC_SETUP | REQUEST) == pr) {
@@ -918,6 +951,34 @@
}
}
+static void
+man1tr6(struct PStack *st, int pr, void *arg)
+{
+ int i;
+ struct l3_process *proc = arg;
+
+ if (!proc) {
+ printk(KERN_ERR "HiSax man1tr6 without proc pr=%04x\n", pr);
+ return;
+ }
+ for (i = 0; i < MANSLLEN; i++)
+ if ((pr == manstatelist[i].primitive) &&
+ ((1 << proc->state) & manstatelist[i].state))
+ break;
+ if (i == MANSLLEN) {
+ if (st->l3.debug & L3_DEB_STATE) {
+ l3_debug(st, "cr %d man1tr6 state %d prim %d unhandled",
+ proc->callref & 0x7f, proc->state, pr);
+ }
+ } else {
+ if (st->l3.debug & L3_DEB_STATE) {
+ l3_debug(st, "cr %d man1tr6 state %d prim %d",
+ proc->callref & 0x7f, proc->state, pr);
+ }
+ manstatelist[i].rout(proc, pr, arg);
+ }
+}
+
void
setstack_1tr6(struct PStack *st)
{
@@ -925,6 +986,7 @@
st->lli.l4l3 = down1tr6;
st->l2.l2l3 = up1tr6;
+ st->l3.l3ml3 = man1tr6;
st->l3.N303 = 0;
strcpy(tmp, l3_1tr6_revision);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)