patch-2.2.14 linux/drivers/isdn/hisax/callc.c

Next file: linux/drivers/isdn/hisax/config.c
Previous file: linux/drivers/isdn/hisax/bkm_a8.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.13/linux/drivers/isdn/hisax/callc.c linux/drivers/isdn/hisax/callc.c
@@ -1,4 +1,4 @@
-/* $Id: callc.c,v 2.37 1999/09/20 19:49:47 keil Exp $
+/* $Id: callc.c,v 2.40 1999/12/19 12:59:56 keil Exp $
 
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
@@ -11,6 +11,16 @@
  *              Fritz Elfert
  *
  * $Log: callc.c,v $
+ * Revision 2.40  1999/12/19 12:59:56  keil
+ * fix leased line handling
+ * and cosmetics
+ *
+ * Revision 2.39  1999/10/14 20:25:28  keil
+ * add a statistic for error monitoring
+ *
+ * Revision 2.38  1999/10/11 22:16:27  keil
+ * Suspend/Resume is possible without explicit ID too
+ *
  * Revision 2.37  1999/09/20 19:49:47  keil
  * Fix wrong init of PStack
  *
@@ -157,7 +167,7 @@
 #define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module))
 #endif	/* MODULE */
 
-const char *lli_revision = "$Revision: 2.37 $";
+const char *lli_revision = "$Revision: 2.40 $";
 
 extern struct IsdnCard cards[];
 extern int nrcards;
@@ -193,8 +203,7 @@
 /*
  * Find card with given driverId
  */
-static inline struct IsdnCardState
-*
+static inline struct IsdnCardState *
 hisax_findcard(int driverid)
 {
 	int i;
@@ -233,39 +242,39 @@
 }
 
 enum {
-        ST_NULL,                /*  0 inactive */
-        ST_OUT_DIAL,            /*  1 outgoing, SETUP send; awaiting confirm */
-        ST_IN_WAIT_LL,          /*  2 incoming call received; wait for LL confirm */
-        ST_IN_ALERT_SENT,       /*  3 incoming call received; ALERT send */
-        ST_IN_WAIT_CONN_ACK,    /*  4 incoming CONNECT send; awaiting CONN_ACK */
-        ST_WAIT_BCONN,          /*  5 CONNECT/CONN_ACK received, awaiting b-channel prot. estbl. */
-        ST_ACTIVE,              /*  6 active, b channel prot. established */
-        ST_WAIT_BRELEASE,       /*  7 call clear. (initiator), awaiting b channel prot. rel. */
-        ST_WAIT_BREL_DISC,      /*  8 call clear. (receiver), DISCONNECT req. received */
-        ST_WAIT_DCOMMAND,       /*  9 call clear. (receiver), awaiting DCHANNEL message */
-        ST_WAIT_DRELEASE,       /* 10 DISCONNECT sent, awaiting RELEASE */
-        ST_WAIT_D_REL_CNF,      /* 11 RELEASE sent, awaiting RELEASE confirm */
-        ST_IN_PROCEED_SEND,     /* 12 incoming call, proceeding send */ 
+	ST_NULL,		/*  0 inactive */
+	ST_OUT_DIAL,		/*  1 outgoing, SETUP send; awaiting confirm */
+	ST_IN_WAIT_LL,		/*  2 incoming call received; wait for LL confirm */
+	ST_IN_ALERT_SENT,	/*  3 incoming call received; ALERT send */
+	ST_IN_WAIT_CONN_ACK,	/*  4 incoming CONNECT send; awaiting CONN_ACK */
+	ST_WAIT_BCONN,		/*  5 CONNECT/CONN_ACK received, awaiting b-channel prot. estbl. */
+	ST_ACTIVE,		/*  6 active, b channel prot. established */
+	ST_WAIT_BRELEASE,	/*  7 call clear. (initiator), awaiting b channel prot. rel. */
+	ST_WAIT_BREL_DISC,	/*  8 call clear. (receiver), DISCONNECT req. received */
+	ST_WAIT_DCOMMAND,	/*  9 call clear. (receiver), awaiting DCHANNEL message */
+	ST_WAIT_DRELEASE,	/* 10 DISCONNECT sent, awaiting RELEASE */
+	ST_WAIT_D_REL_CNF,	/* 11 RELEASE sent, awaiting RELEASE confirm */
+	ST_IN_PROCEED_SEND,	/* 12 incoming call, proceeding send */ 
 };
   
 
 #define STATE_COUNT (ST_IN_PROCEED_SEND + 1)
 
-  static char *strState[] =
-  {
-        "ST_NULL",
-        "ST_OUT_DIAL",
-        "ST_IN_WAIT_LL",
-        "ST_IN_ALERT_SENT",
-        "ST_IN_WAIT_CONN_ACK",
-        "ST_WAIT_BCONN",
-        "ST_ACTIVE",
+static char *strState[] =
+{
+	"ST_NULL",
+	"ST_OUT_DIAL",
+	"ST_IN_WAIT_LL",
+	"ST_IN_ALERT_SENT",
+	"ST_IN_WAIT_CONN_ACK",
+	"ST_WAIT_BCONN",
+	"ST_ACTIVE",
 	"ST_WAIT_BRELEASE",
 	"ST_WAIT_BREL_DISC",
 	"ST_WAIT_DCOMMAND",
 	"ST_WAIT_DRELEASE",
 	"ST_WAIT_D_REL_CNF",
-        "ST_IN_PROCEED_SEND",
+	"ST_IN_PROCEED_SEND",
 };
 
 enum {
@@ -327,19 +336,19 @@
 static inline void
 HL_LL(struct Channel *chanp, int command)
 {
-        isdn_ctrl ic;
+	isdn_ctrl ic;
 
-        ic.driver = chanp->cs->myid;
-        ic.command = command;
-        ic.arg = chanp->chan;
-        chanp->cs->iif.statcallb(&ic);
+	ic.driver = chanp->cs->myid;
+	ic.command = command;
+	ic.arg = chanp->chan;
+	chanp->cs->iif.statcallb(&ic);
 }
 
 static inline void
 lli_deliver_cause(struct Channel *chanp)
 {
-        isdn_ctrl ic;
- 
+	isdn_ctrl ic;
+
 	if (chanp->proc->para.cause == NO_CAUSE)
 		return;
 	ic.driver = chanp->cs->myid;
@@ -357,42 +366,42 @@
 static inline void
 lli_close(struct FsmInst *fi)
 {
-        struct Channel *chanp = fi->userdata;
+	struct Channel *chanp = fi->userdata;
 
-        FsmChangeState(fi, ST_NULL);
-        chanp->Flags = 0;
-        chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
+	FsmChangeState(fi, ST_NULL);
+	chanp->Flags = 0;
+	chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
 }
 
- static void
+static void
 lli_leased_in(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
+	struct Channel *chanp = fi->userdata;
+	isdn_ctrl ic;
+	int ret;
 
-        isdn_ctrl ic;
-        int ret;
- 
-        chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);
-        FsmChangeState(fi, ST_IN_WAIT_LL);
-        if (chanp->debug & 1)
-                link_debug(chanp, 0, "STAT_ICALL_LEASED");
-        ic.driver = chanp->cs->myid;
+	if (!chanp->leased)
+		return;
+	chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);
+	FsmChangeState(fi, ST_IN_WAIT_LL);
+	if (chanp->debug & 1)
+		link_debug(chanp, 0, "STAT_ICALL_LEASED");
+	ic.driver = chanp->cs->myid;
 	ic.command = ((chanp->chan < 2) ? ISDN_STAT_ICALL : ISDN_STAT_ICALLW);
-        ic.arg = chanp->chan;
-        ic.parm.setup.si1 = 7;
-        ic.parm.setup.si2 = 0;
-        ic.parm.setup.plan = 0;
-        ic.parm.setup.screen = 0;
-        sprintf(ic.parm.setup.eazmsn,"%d", chanp->chan + 1);
-        sprintf(ic.parm.setup.phone,"LEASED%d", chanp->cs->myid);
-        ret = chanp->cs->iif.statcallb(&ic);
-        if (chanp->debug & 1)
-                link_debug(chanp, 1, "statcallb ret=%d", ret);
- 
-        if (!ret) {
-                chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
-                FsmChangeState(fi, ST_NULL);
-        }
+	ic.arg = chanp->chan;
+	ic.parm.setup.si1 = 7;
+	ic.parm.setup.si2 = 0;
+	ic.parm.setup.plan = 0;
+	ic.parm.setup.screen = 0;
+	sprintf(ic.parm.setup.eazmsn,"%d", chanp->chan + 1);
+	sprintf(ic.parm.setup.phone,"LEASED%d", chanp->cs->myid);
+	ret = chanp->cs->iif.statcallb(&ic);
+	if (chanp->debug & 1)
+		link_debug(chanp, 1, "statcallb ret=%d", ret);
+	if (!ret) {
+		chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
+		FsmChangeState(fi, ST_NULL);
+	}
 }
 
 
@@ -402,14 +411,14 @@
 static void
 lli_init_bchan_out(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
- 
-        FsmChangeState(fi, ST_WAIT_BCONN);
-        if (chanp->debug & 1)
-                link_debug(chanp, 0, "STAT_DCONN");
-        HL_LL(chanp, ISDN_STAT_DCONN);
-        init_b_st(chanp, 0);
-        chanp->b_st->lli.l4l3(chanp->b_st, DL_ESTABLISH | REQUEST, NULL);
+	struct Channel *chanp = fi->userdata;
+
+	FsmChangeState(fi, ST_WAIT_BCONN);
+	if (chanp->debug & 1)
+		link_debug(chanp, 0, "STAT_DCONN");
+	HL_LL(chanp, ISDN_STAT_DCONN);
+	init_b_st(chanp, 0);
+	chanp->b_st->lli.l4l3(chanp->b_st, DL_ESTABLISH | REQUEST, NULL);
 }
 
 static void
@@ -421,14 +430,13 @@
 	FsmDelTimer(&chanp->dial_timer, 73);
 	chanp->l2_active_protocol = chanp->l2_protocol;
 	chanp->incoming = 0;
-
-        chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);
-        if (chanp->leased) {
-                lli_init_bchan_out(fi, event, arg);
-        } else {
-                FsmChangeState(fi, ST_OUT_DIAL);
-                chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | REQUEST, chanp);
-        }
+	chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);
+	if (chanp->leased) {
+		lli_init_bchan_out(fi, event, arg);
+	} else {
+		FsmChangeState(fi, ST_OUT_DIAL);
+		chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | REQUEST, chanp);
+	}
 }
 
 static void
@@ -436,18 +444,17 @@
 {
 	struct Channel *chanp = fi->userdata;
 
-        FsmDelTimer(&chanp->drel_timer, 60);
-        FsmDelTimer(&chanp->dial_timer, 73);
-        chanp->l2_active_protocol = chanp->l2_protocol;
-        chanp->incoming = 0;
- 
-        chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);
-        if (chanp->leased) {
-                lli_init_bchan_out(fi, event, arg);
-        } else {
-                FsmChangeState(fi, ST_OUT_DIAL);
-                chanp->d_st->lli.l4l3(chanp->d_st, CC_RESUME | REQUEST, chanp);
-        }
+	FsmDelTimer(&chanp->drel_timer, 60);
+	FsmDelTimer(&chanp->dial_timer, 73);
+	chanp->l2_active_protocol = chanp->l2_protocol;
+	chanp->incoming = 0;
+	chanp->cs->cardmsg(chanp->cs, MDL_INFO_SETUP, (void *) (long)chanp->chan);
+	if (chanp->leased) {
+		lli_init_bchan_out(fi, event, arg);
+	} else {
+		FsmChangeState(fi, ST_OUT_DIAL);
+		chanp->d_st->lli.l4l3(chanp->d_st, CC_RESUME | REQUEST, chanp);
+	}
 }
 
 static void
@@ -515,15 +522,15 @@
 				FsmChangeState(fi, ST_IN_ALERT_SENT);
 				chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);
 				break;
-	      	        case 5: /* direct redirect */
-		        case 4: /* Proceeding desired */
+			case 5: /* direct redirect */
+			case 4: /* Proceeding desired */
 				FsmDelTimer(&chanp->drel_timer, 61);
 				FsmChangeState(fi, ST_IN_PROCEED_SEND);
-                                chanp->d_st->lli.l4l3(chanp->d_st, CC_PROCEED_SEND | REQUEST, chanp->proc);
-                                if (ret == 5)
-				 { chanp->setup = ic.parm.setup;
-				   chanp->d_st->lli.l4l3(chanp->d_st, CC_REDIR | REQUEST, chanp->proc);
-                                 }   
+				chanp->d_st->lli.l4l3(chanp->d_st, CC_PROCEED_SEND | REQUEST, chanp->proc);
+				if (ret == 5) {
+					chanp->setup = ic.parm.setup;
+					chanp->d_st->lli.l4l3(chanp->d_st, CC_REDIR | REQUEST, chanp->proc);
+				}
 				break;
 			case 2:	/* Rejecting Call */
 				break;
@@ -584,17 +591,17 @@
 static void
 lli_setup_rsp(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
- 
-        if (chanp->leased) {
-                lli_init_bchan_in(fi, event, arg);
-        } else {
-                FsmChangeState(fi, ST_IN_WAIT_CONN_ACK);
+	struct Channel *chanp = fi->userdata;
+
+	if (chanp->leased) {
+		lli_init_bchan_in(fi, event, arg);
+	} else {
+		FsmChangeState(fi, ST_IN_WAIT_CONN_ACK);
 #ifdef WANT_ALERT
-                chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);
+		chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);
 #endif
-               chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | RESPONSE, chanp->proc);
-       }
+		chanp->d_st->lli.l4l3(chanp->d_st, CC_SETUP | RESPONSE, chanp->proc);
+	}
 }
 
 /* Call suspend */
@@ -610,51 +617,84 @@
 /* Call clearing */
 
 static void
+lli_leased_hup(struct FsmInst *fi, struct Channel *chanp)
+{
+	isdn_ctrl ic;
+
+	ic.driver = chanp->cs->myid;
+	ic.command = ISDN_STAT_CAUSE;
+	ic.arg = chanp->chan;
+	sprintf(ic.parm.num, "L0010");
+	chanp->cs->iif.statcallb(&ic);
+	if (chanp->debug & 1)
+		link_debug(chanp, 0, "STAT_DHUP");
+	HL_LL(chanp, ISDN_STAT_DHUP);
+	lli_close(fi);
+}
+
+static void
 lli_disconnect_req(struct FsmInst *fi, int event, void *arg)
 {
 	struct Channel *chanp = fi->userdata;
 
-	FsmChangeState(fi, ST_WAIT_DRELEASE);
-	chanp->proc->para.cause = 0x10;	/* Normal Call Clearing */
-	chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST, chanp->proc);
+	if (chanp->leased) {
+		lli_leased_hup(fi, chanp);
+	} else {
+		FsmChangeState(fi, ST_WAIT_DRELEASE);
+		chanp->proc->para.cause = 0x10;	/* Normal Call Clearing */
+		chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST,
+			chanp->proc);
+	}
 }
 
 static void
 lli_disconnect_reject(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
+	struct Channel *chanp = fi->userdata;
 
-        FsmChangeState(fi, ST_WAIT_DRELEASE);
-        chanp->proc->para.cause = 0x15;         /* Call Rejected */
-        chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST, chanp->proc);
+	if (chanp->leased) {
+		lli_leased_hup(fi, chanp);
+	} else {
+		FsmChangeState(fi, ST_WAIT_DRELEASE);
+		chanp->proc->para.cause = 0x15;	/* Call Rejected */
+		chanp->d_st->lli.l4l3(chanp->d_st, CC_DISCONNECT | REQUEST,
+			chanp->proc);
+	}
 }
 
 static void
 lli_dhup_close(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
+	struct Channel *chanp = fi->userdata;
 
-        if (chanp->debug & 1)
-                link_debug(chanp, 0, "STAT_DHUP");
-        lli_deliver_cause(chanp);
-        HL_LL(chanp, ISDN_STAT_DHUP);
- 
-        lli_close(fi);
+	if (chanp->leased) {
+		lli_leased_hup(fi, chanp);
+	} else {
+		if (chanp->debug & 1)
+			link_debug(chanp, 0, "STAT_DHUP");
+		lli_deliver_cause(chanp);
+		HL_LL(chanp, ISDN_STAT_DHUP);
+		lli_close(fi);
+	}
 }
 
 static void
 lli_reject_req(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
+	struct Channel *chanp = fi->userdata;
 
+	if (chanp->leased) {
+		lli_leased_hup(fi, chanp);
+		return;
+	}
 #ifndef ALERT_REJECT
-        chanp->proc->para.cause = 0x15;         /* Call Rejected */
-        chanp->d_st->lli.l4l3(chanp->d_st, CC_REJECT | REQUEST, chanp->proc);
-        lli_dhup_close(fi, event, arg);
+	chanp->proc->para.cause = 0x15;	/* Call Rejected */
+	chanp->d_st->lli.l4l3(chanp->d_st, CC_REJECT | REQUEST, chanp->proc);
+	lli_dhup_close(fi, event, arg);
 #else
-        FsmRestartTimer(&chanp->drel_timer, 40, EV_HANGUP, NULL, 63);
-        FsmChangeState(fi, ST_IN_ALERT_SENT);
-        chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);
+	FsmRestartTimer(&chanp->drel_timer, 40, EV_HANGUP, NULL, 63);
+	FsmChangeState(fi, ST_IN_ALERT_SENT);
+	chanp->d_st->lli.l4l3(chanp->d_st, CC_ALERTING | REQUEST, chanp->proc);
 #endif
 }
 
@@ -672,54 +712,45 @@
 lli_start_disc(struct FsmInst *fi, int event, void *arg)
 {
 	struct Channel *chanp = fi->userdata;
-	isdn_ctrl ic;
 
 	if (chanp->leased) {
-		ic.command = ISDN_STAT_CAUSE;
-		ic.arg = chanp->chan;
-		sprintf(ic.parm.num, "L0010");
-		chanp->cs->iif.statcallb(&ic);
-		if (chanp->debug & 1)
-			link_debug(chanp, 0, "STAT_DHUP");
-		HL_LL(chanp, ISDN_STAT_DHUP);
-		lli_close(fi);
+		lli_leased_hup(fi, chanp);
 	} else {
-	        lli_disconnect_req(fi, event, arg);
+		lli_disconnect_req(fi, event, arg);
 	}
 }
 
 static void
 lli_rel_b_disc(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
- 
-        release_b_st(chanp);
-        lli_start_disc(fi, event, arg);
+	struct Channel *chanp = fi->userdata;
+
+	release_b_st(chanp);
+	lli_start_disc(fi, event, arg);
 }
 
 static void
 lli_bhup_disc(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
-  
-        if (chanp->debug & 1)
-                link_debug(chanp, 0, "STAT_BHUP");
-        HL_LL(chanp, ISDN_STAT_BHUP);
+	struct Channel *chanp = fi->userdata;
  
-        lli_rel_b_disc(fi, event, arg);
+	if (chanp->debug & 1)
+		link_debug(chanp, 0, "STAT_BHUP");
+	HL_LL(chanp, ISDN_STAT_BHUP);
+	lli_rel_b_disc(fi, event, arg);
 }
 
 static void
 lli_bhup_rel_b(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
+	struct Channel *chanp = fi->userdata;
 
-        FsmChangeState(fi, ST_WAIT_DCOMMAND);
-        chanp->data_open = 0;
-                if (chanp->debug & 1)
-                link_debug(chanp, 0, "STAT_BHUP");
-        HL_LL(chanp, ISDN_STAT_BHUP);
-        release_b_st(chanp);
+	FsmChangeState(fi, ST_WAIT_DCOMMAND);
+	chanp->data_open = 0;
+	if (chanp->debug & 1)
+		link_debug(chanp, 0, "STAT_BHUP");
+	HL_LL(chanp, ISDN_STAT_BHUP);
+	release_b_st(chanp);
 }
 
 static void
@@ -736,63 +767,65 @@
 static void
 lli_rel_b_dhup(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
+	struct Channel *chanp = fi->userdata;
 
-        release_b_st(chanp);
-        lli_dhup_close(fi, event, arg);
+	release_b_st(chanp);
+	lli_dhup_close(fi, event, arg);
 }
 
 static void
 lli_bhup_dhup(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
+	struct Channel *chanp = fi->userdata;
 
-        if (chanp->debug & 1)
-                link_debug(chanp, 0, "STAT_BHUP");
-        HL_LL(chanp, ISDN_STAT_BHUP);
- 
-        lli_rel_b_dhup(fi, event, arg);
+	if (chanp->debug & 1)
+		link_debug(chanp, 0, "STAT_BHUP");
+	HL_LL(chanp, ISDN_STAT_BHUP);
+	lli_rel_b_dhup(fi, event, arg);
 }
 
 static void
 lli_abort(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
+	struct Channel *chanp = fi->userdata;
 
-        chanp->data_open = 0;
-        chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL);
- 
-        lli_bhup_dhup(fi, event, arg);
+	chanp->data_open = 0;
+	chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL);
+	lli_bhup_dhup(fi, event, arg);
 }
  
 static void
 lli_release_req(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
- 
-        FsmChangeState(fi, ST_WAIT_D_REL_CNF);
-        chanp->d_st->lli.l4l3(chanp->d_st, CC_RELEASE | REQUEST, chanp->proc);
+	struct Channel *chanp = fi->userdata;
+
+	if (chanp->leased) {
+		lli_leased_hup(fi, chanp);
+	} else {
+		FsmChangeState(fi, ST_WAIT_D_REL_CNF);
+		chanp->d_st->lli.l4l3(chanp->d_st, CC_RELEASE | REQUEST,
+			chanp->proc);
+	}
 }
 
 static void
 lli_rel_b_release_req(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
- 
-        release_b_st(chanp);
-        lli_release_req(fi, event, arg);
+	struct Channel *chanp = fi->userdata;
+
+	release_b_st(chanp);
+	lli_release_req(fi, event, arg);
 }
 
 static void
 lli_bhup_release_req(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
- 
-        if (chanp->debug & 1)
-                link_debug(chanp, 0, "STAT_BHUP");
-        HL_LL(chanp, ISDN_STAT_BHUP);
+	struct Channel *chanp = fi->userdata;
  
-        lli_rel_b_release_req(fi, event, arg);
+	if (chanp->debug & 1)
+		link_debug(chanp, 0, "STAT_BHUP");
+	HL_LL(chanp, ISDN_STAT_BHUP);
+	lli_rel_b_release_req(fi, event, arg);
 }
 
 
@@ -819,7 +852,7 @@
 
 	if (chanp->debug & 1)
 		link_debug(chanp, 0, "STAT_DHUP");
-        HL_LL(chanp, ISDN_STAT_DHUP); 
+	HL_LL(chanp, ISDN_STAT_DHUP); 
 }
 
 static void
@@ -830,67 +863,65 @@
 	if (chanp->debug & 1)
 		link_debug(chanp, 0, "STAT_DHUP");
 	HL_LL(chanp, ISDN_STAT_DHUP);
-        lli_close(fi); 
+	lli_close(fi); 
 }
 
 static void
 lli_error(struct FsmInst *fi, int event, void *arg)
 {
-        FsmChangeState(fi, ST_WAIT_DRELEASE);
+	FsmChangeState(fi, ST_WAIT_DRELEASE);
 }
 
 static void
 lli_failure_l(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
-        isdn_ctrl ic;
+	struct Channel *chanp = fi->userdata;
+	isdn_ctrl ic;
 
-        FsmChangeState(fi, ST_NULL);
-        ic.driver = chanp->cs->myid;
-        ic.command = ISDN_STAT_CAUSE;
-        ic.arg = chanp->chan;
-        sprintf(ic.parm.num, "L%02X%02X", 0, 0x2f);
-        chanp->cs->iif.statcallb(&ic);
-        HL_LL(chanp, ISDN_STAT_DHUP);
-        chanp->Flags = 0;
-        chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
+	FsmChangeState(fi, ST_NULL);
+	ic.driver = chanp->cs->myid;
+	ic.command = ISDN_STAT_CAUSE;
+	ic.arg = chanp->chan;
+	sprintf(ic.parm.num, "L%02X%02X", 0, 0x2f);
+	chanp->cs->iif.statcallb(&ic);
+	HL_LL(chanp, ISDN_STAT_DHUP);
+	chanp->Flags = 0;
+	chanp->cs->cardmsg(chanp->cs, MDL_INFO_REL, (void *) (long)chanp->chan);
 }
 
 static void
 lli_rel_b_fail(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
+	struct Channel *chanp = fi->userdata;
 
-        release_b_st(chanp);
-        lli_failure_l(fi, event, arg);
+	release_b_st(chanp);
+	lli_failure_l(fi, event, arg);
 }
 
 static void
 lli_bhup_fail(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
+	struct Channel *chanp = fi->userdata;
 
-        if (chanp->debug & 1)
-                link_debug(chanp, 0, "STAT_BHUP");
-        HL_LL(chanp, ISDN_STAT_BHUP);
- 
-        lli_rel_b_fail(fi, event, arg);
+	if (chanp->debug & 1)
+		link_debug(chanp, 0, "STAT_BHUP");
+	HL_LL(chanp, ISDN_STAT_BHUP);
+	lli_rel_b_fail(fi, event, arg);
 }
 
 static void
 lli_failure_a(struct FsmInst *fi, int event, void *arg)
 {
-        struct Channel *chanp = fi->userdata;
+	struct Channel *chanp = fi->userdata;
 
-        chanp->data_open = 0;
-        chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL);
- 
-        lli_bhup_fail(fi, event, arg);
+	chanp->data_open = 0;
+	chanp->b_st->lli.l4l3(chanp->b_st, DL_RELEASE | REQUEST, NULL);
+	lli_bhup_fail(fi, event, arg);
 }
 
-  /* *INDENT-OFF* */
-  static struct FsmNode fnlist[] HISAX_INITDATA =
-  {
+/* *INDENT-OFF* */
+static struct FsmNode fnlist[] HISAX_INITDATA =
+{
         {ST_NULL,               EV_DIAL,                lli_prep_dialout},
         {ST_NULL,               EV_RESUME,              lli_resume},
         {ST_NULL,               EV_SETUP_IND,           lli_deliver_call},
@@ -953,10 +984,9 @@
         {ST_WAIT_D_REL_CNF,     EV_RELEASE,             lli_dhup_close},
         {ST_WAIT_D_REL_CNF,     EV_DIAL,                lli_dchan_not_ready},
 };
-  /* *INDENT-ON* */
+/* *INDENT-ON* */
 
-
-  #define FNCOUNT (sizeof(fnlist)/sizeof(struct FsmNode))
+#define FNCOUNT (sizeof(fnlist)/sizeof(struct FsmNode))
 
 HISAX_INITFUNC(void
 CallcNew(void))
@@ -979,9 +1009,9 @@
 {
 	struct PStack *st = chanp->b_st;
 
-        if(test_and_clear_bit(FLG_START_B, &chanp->Flags)) {
-                chanp->bcs->BC_Close(chanp->bcs);
-                switch (chanp->l2_active_protocol) {
+	if(test_and_clear_bit(FLG_START_B, &chanp->Flags)) {
+		chanp->bcs->BC_Close(chanp->bcs);
+		switch (chanp->l2_active_protocol) {
 			case (ISDN_PROTO_L2_X75I):
 				releasestack_isdnl2(st);
 				break;
@@ -989,10 +1019,10 @@
 			case (ISDN_PROTO_L2_TRANS):
 			case (ISDN_PROTO_L2_MODEM):
 			case (ISDN_PROTO_L2_FAX):
-                                releasestack_transl2(st);
-                                break;
-                }
-        } 
+				releasestack_transl2(st);
+				break;
+		}
+	} 
 }
 
 struct Channel
@@ -1007,10 +1037,10 @@
 	else
 		i=0;
 
-        if (!bch) 
-         { i = 2; /* virtual channel */
-           chanp += 2;
-         }
+	if (!bch) {
+		i = 2; /* virtual channel */
+		chanp += 2;
+	}
 
 	while (i < ((bch) ? cs->chanlimit : (2 + MAX_WAITING_CALLS))) {
 		if (chanp->fi.state == ST_NULL)
@@ -1019,17 +1049,17 @@
 		i++;
 	}
 
-        if (bch) /* number of channels is limited */ 
-         { i = 2; /* virtual channel */
-           chanp = st->lli.userdata;
-	   chanp += i;
-	   while (i < (2 + MAX_WAITING_CALLS)) {
-		if (chanp->fi.state == ST_NULL)
-			return (chanp);
-		chanp++;
-		i++;
-	   }
-         }
+	if (bch) /* number of channels is limited */ {
+		i = 2; /* virtual channel */
+		chanp = st->lli.userdata;
+		chanp += i;
+		while (i < (2 + MAX_WAITING_CALLS)) {
+			if (chanp->fi.state == ST_NULL)
+				return (chanp);
+			chanp++;
+			i++;
+		}
+	}
 	return (NULL);
 }
 
@@ -1047,19 +1077,19 @@
 dchan_l3l4(struct PStack *st, int pr, void *arg)
 {
 	struct l3_process *pc = arg;
-        struct IsdnCardState *cs = st->l1.hardware;
+	struct IsdnCardState *cs = st->l1.hardware;
 	struct Channel *chanp;
 
-        if(!pc)
-                return;
- 
-        if (pr == (CC_SETUP | INDICATION)) {
-                if (!(chanp = selectfreechannel(pc->st, pc->para.bchannel))) {
-                        pc->para.cause = 0x11;          /* User busy */
-                        pc->st->lli.l4l3(pc->st, CC_REJECT | REQUEST, pc);
-                } else {
-                        chanp->proc = pc;
-                        pc->chan = chanp;
+	if(!pc)
+		return;
+
+	if (pr == (CC_SETUP | INDICATION)) {
+		if (!(chanp = selectfreechannel(pc->st, pc->para.bchannel))) {
+			pc->para.cause = 0x11;	/* User busy */
+			pc->st->lli.l4l3(pc->st, CC_REJECT | REQUEST, pc);
+		} else {
+			chanp->proc = pc;
+			pc->chan = chanp;
 			FsmEvent(&chanp->fi, EV_SETUP_IND, NULL);
 		}
 		return;
@@ -1115,8 +1145,8 @@
 			break;
 		case (CC_REDIR | INDICATION):
 			stat_redir_result(cs, chanp->chan, pc->redir_result); 
-			break;                         
-		default:
+			break;
+			default:
 			if (chanp->debug & 0x800) {
 				HiSax_putstatus(chanp->cs, "Ch",
 					"%d L3->L4 unknown primitiv %#x",
@@ -1141,7 +1171,7 @@
 	(*stp)->l2.l2l1 = dummy_pstack;
 	(*stp)->l2.l2l3 = dummy_pstack;
 	(*stp)->l3.l3l2 = dummy_pstack;
-        (*stp)->l3.l3ml3 = dummy_pstack;
+	(*stp)->l3.l3ml3 = dummy_pstack;
 	(*stp)->l3.l3l4 = dummy_pstack;
 	(*stp)->lli.l4l3 = dummy_pstack;
 	(*stp)->ma.layer = dummy_pstack;
@@ -1224,8 +1254,8 @@
 }
 
 int
-CallcNewChan(struct IsdnCardState *csta)
-{       int i;
+CallcNewChan(struct IsdnCardState *csta) {
+	int i;
 
 	chancount += 2;
 	init_chan(0, csta);
@@ -1234,8 +1264,7 @@
 
 	for (i = 0; i < MAX_WAITING_CALLS; i++) 
 		init_chan(i+2,csta);
-	printk(KERN_INFO "HiSax: MAX_WAITING_CALLS added\n");        
-
+	printk(KERN_INFO "HiSax: MAX_WAITING_CALLS added\n");
 	if (test_bit(FLG_PTP, &csta->channel->d_st->l2.flag)) {
 		printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n");
 		csta->channel->d_st->lli.l4l3(csta->channel->d_st,
@@ -1266,13 +1295,13 @@
 	for (i = 0; i < 2; i++) {
 		FsmDelTimer(&csta->channel[i].drel_timer, 74);
 		FsmDelTimer(&csta->channel[i].dial_timer, 75);
-                if (i || test_bit(FLG_TWO_DCHAN, &csta->HW_Flags))
-                        release_d_st(csta->channel + i);
-                if (csta->channel[i].b_st) {
-                        release_b_st(csta->channel + i);
-                        kfree(csta->channel[i].b_st);
-                        csta->channel[i].b_st = NULL;
-                } else
+		if (i || test_bit(FLG_TWO_DCHAN, &csta->HW_Flags))
+			release_d_st(csta->channel + i);
+		if (csta->channel[i].b_st) {
+			release_b_st(csta->channel + i);
+			kfree(csta->channel[i].b_st);
+			csta->channel[i].b_st = NULL;
+		} else
 			printk(KERN_WARNING "CallcFreeChan b_st ch%d allready freed\n", i);
 		if (i || test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) {
 			release_d_st(csta->channel + i);
@@ -1305,7 +1334,7 @@
 			break;
 		default:
 			printk(KERN_WARNING "lldata_handler unknown primitive %#x\n",
-			       pr);
+				pr);
 			break;
 	}
 }
@@ -1335,7 +1364,7 @@
 			break;
 		default:
 			printk(KERN_WARNING "lltrans_handler unknown primitive %#x\n",
-			       pr);
+				pr);
 			break;
 	}
 }
@@ -1438,7 +1467,7 @@
 			break;
 		default:
 			printk(KERN_WARNING "transd_l4l3 unknown primitive %#x\n",
-			       pr);
+				pr);
 			break;
 	}
 }
@@ -1478,11 +1507,6 @@
 }
 
 static void
-channel_report(struct Channel *chanp)
-{
-}
-
-static void
 distr_debug(struct IsdnCardState *csta, int debugflags)
 {
 	int i;
@@ -1515,7 +1539,6 @@
 {
 	char *t = tmpbuf;
 
-	t += sprintf(tmpbuf, "%d CAPIMSG", chanp->chan);
 	t += QuickHex(t, (u_char *)cm, (cm->Length>50)? 50: cm->Length);
 	t--;
 	*t= 0;
@@ -1532,20 +1555,16 @@
 		return;
 	switch(cm->para[3]) {
 		case 4: /* Suspend */
-			if (cm->para[5]) {
-				strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1);
-				FsmEvent(&chanp->fi, EV_SUSPEND, cm);
-			}
+			strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1);
+			FsmEvent(&chanp->fi, EV_SUSPEND, cm);
 			break;
 		case 5: /* Resume */
-			if (cm->para[5]) {
-				strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1);
-				if (chanp->fi.state == ST_NULL) {
-					FsmEvent(&chanp->fi, EV_RESUME, cm);
-				} else {
-					FsmDelTimer(&chanp->dial_timer, 72);
-					FsmAddTimer(&chanp->dial_timer, 80, EV_RESUME, cm, 73);
-				}
+			strncpy(chanp->setup.phone, &cm->para[5], cm->para[5] +1);
+			if (chanp->fi.state == ST_NULL) {
+				FsmEvent(&chanp->fi, EV_RESUME, cm);
+			} else {
+				FsmDelTimer(&chanp->dial_timer, 72);
+				FsmAddTimer(&chanp->dial_timer, 80, EV_RESUME, cm, 73);
 			}
 			break;
 	}
@@ -1602,7 +1621,7 @@
 	if (!csta) {
 		printk(KERN_ERR
 		"HiSax: if_command %d called with invalid driverId %d!\n",
-		       ic->command, ic->driver);
+			ic->command, ic->driver);
 		return -ENODEV;
 	}
 	switch (ic->command) {
@@ -1697,9 +1716,8 @@
 		case (ISDN_CMD_IOCTL):
 			switch (ic->arg) {
 				case (0):
-					HiSax_reportcard(csta->cardnr);
-					for (i = 0; i < 2; i++)
-						channel_report(&csta->channel[i]);
+					num = *(unsigned int *) ic->parm.num;
+					HiSax_reportcard(csta->cardnr, num);
 					break;
 				case (1):
 					num = *(unsigned int *) ic->parm.num;
@@ -1776,11 +1794,18 @@
 					num = *(unsigned int *) ic->parm.num;
 					chanp = csta->channel + (num & 1);
 					num = num >>1;
-					test_and_set_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag);
-					chanp->d_st->l2.tei = num;
-					HiSax_putstatus(csta, "set card ", "in FIXED TEI (%d) mode", num);
-					printk(KERN_DEBUG "HiSax: set card in FIXED TEI (%d) mode\n",
-						num);
+					if (num == 127) {
+						test_and_clear_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag);
+						chanp->d_st->l2.tei = -1;
+						HiSax_putstatus(csta, "set card ", "in VAR TEI mode");
+						printk(KERN_DEBUG "HiSax: set card in VAR TEI mode\n");
+					} else {
+						test_and_set_bit(FLG_FIXED_TEI, &chanp->d_st->l2.flag);
+						chanp->d_st->l2.tei = num;
+						HiSax_putstatus(csta, "set card ", "in FIXED TEI (%d) mode", num);
+						printk(KERN_DEBUG "HiSax: set card in FIXED TEI (%d) mode\n",
+							num);
+					}
 					chanp->d_st->lli.l4l3(chanp->d_st,
 						DL_ESTABLISH | REQUEST, NULL);
 					break;
@@ -1816,7 +1841,7 @@
 					if (csta->auxcmd)
 						return(csta->auxcmd(csta, ic));
 					printk(KERN_DEBUG "HiSax: invalid ioclt %d\n",
-					       (int) ic->arg);
+						(int) ic->arg);
 					return (-EINVAL);
 			}
 			break;
@@ -1844,11 +1869,11 @@
 			break;
 
 		/* protocol specific io commands */
-	        case (ISDN_CMD_PROT_IO):
+		case (ISDN_CMD_PROT_IO):
 			for (st = csta->stlist; st; st = st->next)
 				if (st->protocol == (ic->arg & 0xFF))
 					return(st->lli.l4l3_proto(st, ic));
-			return(-EINVAL);                     
+			return(-EINVAL);
 			break;
 		default:
 			if (csta->auxcmd)
@@ -1870,7 +1895,7 @@
 
 	if (!csta) {
 		printk(KERN_ERR
-		    "HiSax: if_sendbuf called with invalid driverId!\n");
+			"HiSax: if_sendbuf called with invalid driverId!\n");
 		return -ENODEV;
 	}
 	chanp = csta->channel + chan;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)