patch-2.1.42 linux/drivers/isdn/hisax/callc.c
Next file: linux/drivers/isdn/hisax/config.c
Previous file: linux/drivers/isdn/hisax/avm_a1.c
Back to the patch index
Back to the overall index
- Lines: 475
- Date:
Wed May 28 10:49:09 1997
- Orig file:
v2.1.41/linux/drivers/isdn/hisax/callc.c
- Orig date:
Thu Feb 27 10:57:29 1997
diff -u --recursive --new-file v2.1.41/linux/drivers/isdn/hisax/callc.c linux/drivers/isdn/hisax/callc.c
@@ -1,4 +1,4 @@
-/* $Id: callc.c,v 1.20 1997/02/17 00:32:47 keil Exp $
+/* $Id: callc.c,v 1.29 1997/04/23 20:09:49 fritz Exp $
* Author Karsten Keil (keil@temic-ech.spacenet.de)
* based on the teles driver from Jan den Ouden
@@ -7,6 +7,34 @@
* Fritz Elfert
*
* $Log: callc.c,v $
+ * Revision 1.29 1997/04/23 20:09:49 fritz
+ * Removed tmp, used by removed debugging code.
+ *
+ * Revision 1.28 1997/04/21 13:42:25 keil
+ * Remove unneeded debug
+ *
+ * Revision 1.27 1997/04/16 14:21:01 keil
+ * remove unused variable
+ *
+ * Revision 1.26 1997/04/13 19:55:21 keil
+ * Changes in debugging code
+ *
+ * Revision 1.25 1997/04/06 22:54:08 keil
+ * Using SKB's
+ *
+ * Revision 1.24 1997/03/05 11:28:03 keil
+ * fixed undefined l2tei procedure
+ * a layer1 release delete now the drel timer
+ *
+ * Revision 1.23 1997/03/04 23:07:42 keil
+ * bugfix dial parameter
+ *
+ * Revision 1.22 1997/02/27 13:51:55 keil
+ * Reset B-channel (dlc) statemachine in every release
+ *
+ * Revision 1.21 1997/02/19 09:24:27 keil
+ * Bugfix: Hangup to LL if a ttyI rings
+ *
* Revision 1.20 1997/02/17 00:32:47 keil
* Bugfix: No Busy reported to LL
*
@@ -81,7 +109,7 @@
#endif
#endif /* MODULE */
-const char *l4_revision = "$Revision: 1.20 $";
+const char *l4_revision = "$Revision: 1.29 $";
extern struct IsdnCard cards[];
extern int nrcards;
@@ -304,18 +332,18 @@
l4_deliver_cause(struct Channel *chanp)
{
isdn_ctrl ic;
-
- if (chanp->para.cause<0)
+
+ if (chanp->para.cause < 0)
return;
ic.driver = chanp->sp->myid;
ic.command = ISDN_STAT_CAUSE;
ic.arg = chanp->chan;
if (chanp->sp->protocol == ISDN_PTYPE_EURO)
- sprintf(ic.parm.num, "E%02X%02X", chanp->para.loc,
- chanp->para.cause);
+ sprintf(ic.parm.num, "E%02X%02X", chanp->para.loc & 0x7f,
+ chanp->para.cause & 0x7f);
else
- sprintf(ic.parm.num, "%02X%02X", chanp->para.loc,
- chanp->para.cause);
+ sprintf(ic.parm.num, "%02X%02X", chanp->para.loc & 0x7f,
+ chanp->para.cause & 0x7f);
chanp->sp->iif.statcallb(&ic);
}
@@ -325,15 +353,11 @@
static void
l4_prep_dialout(struct FsmInst *fi, int event, void *arg)
{
- isdn_ctrl *ic = arg;
struct Channel *chanp = fi->userdata;
FsmChangeState(fi, ST_OUT_WAIT_D);
FsmDelTimer(&chanp->drel_timer, 60);
FsmDelTimer(&chanp->dial_timer, 73);
- chanp->para.setup = ic->parm.setup;
- if (!strcmp(chanp->para.setup.eazmsn, "0"))
- chanp->para.setup.eazmsn[0] = '\0';
chanp->l2_active_protocol = chanp->l2_protocol;
chanp->incoming = 0;
@@ -614,8 +638,9 @@
{
struct Channel *chanp = fi->userdata;
- chanp->Flags = 0;
FsmChangeState(fi, ST_NULL);
+ chanp->Flags = 0;
+ FsmDelTimer(&chanp->drel_timer, 63);
}
static void
@@ -718,11 +743,9 @@
release_ds(chanp);
RESBIT(chanp->Flags, FLG_START_B);
}
- if (chanp->Flags & (FLG_LL_DCONN | FLG_CALL_SEND)) {
+ if (chanp->Flags & (FLG_LL_DCONN | FLG_CALL_SEND | FLG_CALL_ALERT)) {
if (chanp->debug & 1)
link_debug(chanp, "STAT_DHUP", 0);
- RESBIT(chanp->Flags, FLG_LL_DCONN);
- RESBIT(chanp->Flags, FLG_CALL_SEND);
l4_deliver_cause(chanp);
ic.driver = chanp->sp->myid;
ic.command = ISDN_STAT_DHUP;
@@ -734,6 +757,8 @@
RESBIT(chanp->Flags, FLG_DISC_SEND);
RESBIT(chanp->Flags, FLG_CALL_REC);
RESBIT(chanp->Flags, FLG_CALL_ALERT);
+ RESBIT(chanp->Flags, FLG_LL_DCONN);
+ RESBIT(chanp->Flags, FLG_CALL_SEND);
}
static void
@@ -762,11 +787,9 @@
release_ds(chanp);
RESBIT(chanp->Flags, FLG_START_B);
}
- if (chanp->Flags & (FLG_LL_DCONN | FLG_CALL_SEND)) {
+ if (chanp->Flags & (FLG_LL_DCONN | FLG_CALL_SEND | FLG_CALL_ALERT)) {
if (chanp->debug & 1)
link_debug(chanp, "STAT_DHUP", 0);
- RESBIT(chanp->Flags, FLG_LL_DCONN);
- RESBIT(chanp->Flags, FLG_CALL_SEND);
l4_deliver_cause(chanp);
ic.driver = chanp->sp->myid;
ic.command = ISDN_STAT_DHUP;
@@ -778,6 +801,8 @@
RESBIT(chanp->Flags, FLG_DISC_SEND);
RESBIT(chanp->Flags, FLG_CALL_REC);
RESBIT(chanp->Flags, FLG_CALL_ALERT);
+ RESBIT(chanp->Flags, FLG_LL_DCONN);
+ RESBIT(chanp->Flags, FLG_CALL_SEND);
}
static void
@@ -802,18 +827,17 @@
release_ds(chanp);
RESBIT(chanp->Flags, FLG_START_B);
}
- if (chanp->Flags & (FLG_LL_DCONN | FLG_CALL_SEND)) {
+ if (chanp->Flags & (FLG_LL_DCONN | FLG_CALL_SEND | FLG_CALL_ALERT)) {
if (chanp->debug & 1)
link_debug(chanp, "STAT_DHUP", 0);
- RESBIT(chanp->Flags, FLG_LL_DCONN);
- RESBIT(chanp->Flags, FLG_CALL_SEND);
- RESBIT(chanp->Flags, FLG_CALL_ALERT);
l4_deliver_cause(chanp);
ic.driver = chanp->sp->myid;
ic.command = ISDN_STAT_DHUP;
ic.arg = chanp->chan;
chanp->sp->iif.statcallb(&ic);
}
+ RESBIT(chanp->Flags, FLG_LL_DCONN);
+ RESBIT(chanp->Flags, FLG_CALL_SEND);
RESBIT(chanp->Flags, FLG_CALL_ALERT);
chanp->is.l4.l4l3(&chanp->is, CC_RELEASE_REQ, NULL);
}
@@ -964,11 +988,11 @@
link_debug(chanp, "STAT_DHUP", 0);
RESBIT(chanp->Flags, FLG_LL_DCONN);
if (chanp->sp->protocol == ISDN_PTYPE_EURO) {
- chanp->para.cause = 0x2f;
- chanp->para.loc = 0;
+ chanp->para.cause = 0x2f;
+ chanp->para.loc = 0;
} else {
- chanp->para.cause = 0x70;
- chanp->para.loc = 0;
+ chanp->para.cause = 0x70;
+ chanp->para.loc = 0;
}
l4_deliver_cause(chanp);
ic.driver = chanp->sp->myid;
@@ -986,6 +1010,7 @@
{ST_NULL, EV_DIAL, l4_prep_dialout},
{ST_NULL, EV_SETUP_IND, l4_start_dchan},
{ST_NULL, EV_SHUTDOWN_D, l4_shutdown_d},
+ {ST_NULL, EV_DLRL, l4_go_null},
{ST_OUT_WAIT_D, EV_DLEST, l4_do_dialout},
{ST_OUT_WAIT_D, EV_DLRL, l4_no_dchan},
{ST_OUT_WAIT_D, EV_HANGUP, l4_no_dchan},
@@ -1057,10 +1082,6 @@
-
-
-
-
#define FNCOUNT (sizeof(fnlist)/sizeof(struct FsmNode))
static void
@@ -1194,6 +1215,9 @@
+
+
+
#define LC_FN_COUNT (sizeof(LcFnList)/sizeof(struct FsmNode))
void
@@ -1240,6 +1264,9 @@
releasestack_transl2(st);
break;
}
+ /* Reset B-Channel Statemachine */
+ FsmDelTimer(&chanp->lc_b.act_timer, 79);
+ FsmChangeState(&chanp->lc_b.lcfi, ST_LC_NULL);
}
static void
@@ -1306,8 +1333,18 @@
}
static void
-ll_handler(struct PStack *st, int pr,
- struct BufHeader *ibh)
+l2tei_dummy(struct PStack *st, int pr, void *arg)
+{
+ struct Channel *chanp = (struct Channel *) st->l4.userdata;
+ char tmp[64], tm[32];
+
+ jiftime(tm, jiffies);
+ sprintf(tmp, "%s Channel %d Warning! Dummy l2tei called pr=%d\n", tm, chanp->chan, pr);
+ HiSax_putstatus(chanp->sp, tmp);
+}
+
+static void
+ll_handler(struct PStack *st, int pr, void *arg)
{
struct Channel *chanp = (struct Channel *) st->l4.userdata;
char tmp[64], tm[32];
@@ -1347,9 +1384,12 @@
FsmEvent(&chanp->fi, EV_RELEASE_ERR, NULL);
break;
default:
- jiftime(tm, jiffies);
- sprintf(tmp, "%s Channel %d L3->L4 unknown primitiv %d\n", tm, chanp->chan, pr);
- HiSax_putstatus(chanp->sp, tmp);
+ if (chanp->debug & 2048) {
+ jiftime(tm, jiffies);
+ sprintf(tmp, "%s Channel %d L3->L4 unknown primitiv %d\n",
+ tm, chanp->chan, pr);
+ HiSax_putstatus(chanp->sp, tmp);
+ }
}
}
@@ -1525,7 +1565,6 @@
releasestack_isdnl2(st);
releasestack_isdnl3(st);
HiSax_rmlist(st->l1.hardware, st);
- BufQueueRelease(&st->l2.i_queue);
}
void
@@ -1546,23 +1585,19 @@
}
static void
-lldata_handler(struct PStack *st, int pr,
- void *arg)
+lldata_handler(struct PStack *st, int pr, void *arg)
{
struct Channel *chanp = (struct Channel *) st->l4.userdata;
- byte *ptr;
- int size;
- struct BufHeader *ibh = arg;
+ struct sk_buff *skb = arg;
switch (pr) {
case (DL_DATA):
- if (chanp->data_open) {
- ptr = DATAPTR(ibh);
- ptr += chanp->ds.l2.ihsize;
- size = ibh->datasize - chanp->ds.l2.ihsize;
- chanp->sp->iif.rcvcallb(chanp->sp->myid, chanp->chan, ptr, size);
+ if (chanp->data_open)
+ chanp->sp->iif.rcvcallb_skb(chanp->sp->myid, chanp->chan, skb);
+ else {
+ SET_SKB_FREE(skb);
+ dev_kfree_skb(skb, FREE_READ);
}
- BufPoolRelease(ibh);
break;
default:
printk(KERN_WARNING "lldata_handler unknown primitive %d\n",
@@ -1572,19 +1607,19 @@
}
static void
-lltrans_handler(struct PStack *st, int pr,
- struct BufHeader *ibh)
+lltrans_handler(struct PStack *st, int pr, void *arg)
{
struct Channel *chanp = (struct Channel *) st->l4.userdata;
- byte *ptr;
+ struct sk_buff *skb = arg;
switch (pr) {
case (PH_DATA):
- if (chanp->data_open) {
- ptr = DATAPTR(ibh);
- chanp->sp->iif.rcvcallb(chanp->sp->myid, chanp->chan, ptr, ibh->datasize);
+ if (chanp->data_open)
+ chanp->sp->iif.rcvcallb_skb(chanp->sp->myid, chanp->chan, skb);
+ else {
+ SET_SKB_FREE(skb);
+ dev_kfree_skb(skb, FREE_READ);
}
- BufPoolRelease(ibh);
break;
default:
printk(KERN_WARNING "lltrans_handler unknown primitive %d\n",
@@ -1616,7 +1651,6 @@
st->l1.hardware = sp;
hsp->mode = 2;
- hsp->transbufsize = 4000;
if (setstack_hscx(st, hsp))
return (-1);
@@ -1637,6 +1671,7 @@
st->l2.l2l3 = lldata_handler;
st->l1.l1man = dcc_l1man;
st->l2.l2man = dcc_l2man;
+ st->l2.l2tei = l2tei_dummy;
st->l4.userdata = chanp;
st->l4.l1writewakeup = NULL;
st->l4.l2writewakeup = ll_writewakeup;
@@ -1726,16 +1761,19 @@
if (chanp->debug & 1) {
sprintf(tmp, "DIAL %s -> %s (%d,%d)",
ic->parm.setup.eazmsn, ic->parm.setup.phone,
- ic->parm.setup.si1, ic->parm.setup.si2);
+ ic->parm.setup.si1, ic->parm.setup.si2);
link_debug(chanp, tmp, 1);
}
+ chanp->para.setup = ic->parm.setup;
+ if (!strcmp(chanp->para.setup.eazmsn, "0"))
+ chanp->para.setup.eazmsn[0] = '\0';
/* this solution is dirty and may be change, if
* we make a callreference based callmanager */
if (chanp->fi.state == ST_NULL) {
- FsmEvent(&chanp->fi, EV_DIAL, ic);
+ FsmEvent(&chanp->fi, EV_DIAL, NULL);
} else {
FsmDelTimer(&chanp->dial_timer, 70);
- FsmAddTimer(&chanp->dial_timer, 50, EV_DIAL, ic, 71);
+ FsmAddTimer(&chanp->dial_timer, 50, EV_DIAL, NULL, 71);
}
break;
case (ISDN_CMD_ACCEPTB):
@@ -1849,7 +1887,7 @@
case (11):
csta->debug = *(unsigned int *) ic->parm.num;
sprintf(tmp, "l1 debugging flags card %d set to %x\n",
- csta->cardnr + 1, csta->debug);
+ csta->cardnr + 1, csta->debug);
HiSax_putstatus(cards[0].sp, tmp);
printk(KERN_DEBUG "HiSax: %s", tmp);
break;
@@ -1875,14 +1913,14 @@
}
int
-HiSax_writebuf(int id, int chan, const u_char * buf, int count, int user)
+HiSax_writebuf_skb(int id, int chan, struct sk_buff *skb)
{
struct IsdnCardState *csta = hisax_findcard(id);
struct Channel *chanp;
struct PStack *st;
- struct BufHeader *ibh;
- int err, i;
- byte *ptr;
+ int len = skb->len;
+ unsigned long flags;
+ struct sk_buff *nskb;
char tmp[64];
if (!csta) {
@@ -1896,51 +1934,38 @@
link_debug(chanp, "writebuf: channel not open", 1);
return -EIO;
}
- err = BufPoolGet(&ibh, st->l1.sbufpool, GFP_ATOMIC, st, 21);
- if (err) {
- /* Must return 0 here, since this is not an error
- * but a temporary lack of resources.
- */
- if (chanp->debug & 1) {
- sprintf(tmp, "writebuf: no buffers for %d bytes", count);
- link_debug(chanp, tmp, 1);
- }
- return 0;
- }
-#if 0
- if (chanp->debug & 1) {
- sprintf(tmp, "writebuf: %d bytes", count);
- link_debug(chanp, tmp, 1);
- }
-#endif
- ptr = DATAPTR(ibh);
- if (chanp->lc_b.l2_establish)
- i = st->l2.ihsize;
- else
- i = 0;
-
- if ((count + i) > BUFFER_SIZE(HSCX_SBUF_ORDER, HSCX_SBUF_BPPS)) {
- sprintf(tmp, "writebuf: packet too large (%d bytes)", count + i);
+ if (len > MAX_DATA_SIZE) {
+ sprintf(tmp, "writebuf: packet too large (%d bytes)", len);
printk(KERN_WARNING "HiSax_%s !\n", tmp);
link_debug(chanp, tmp, 1);
- return (-EINVAL);
+ return -EINVAL;
}
- ptr += i;
-
- if (user)
- copy_from_user(ptr, buf, count);
- else
- memcpy(ptr, buf, count);
- ibh->datasize = count + i;
-
- if (chanp->data_open) {
- if (chanp->lc_b.l2_establish)
- chanp->ds.l3.l3l2(&chanp->ds, DL_DATA, ibh);
- else
- chanp->ds.l2.l2l1(&chanp->ds, PH_DATA, ibh);
- return (count);
- } else {
- BufPoolRelease(ibh);
- return (0);
+ if (len) {
+ if ((len + csta->hs[chanp->hscx].tx_cnt) > MAX_DATA_MEM) {
+ /* Must return 0 here, since this is not an error
+ * but a temporary lack of resources.
+ */
+ if (chanp->debug & 2048) {
+ sprintf(tmp, "writebuf: no buffers for %d bytes", len);
+ link_debug(chanp, tmp, 1);
+ }
+ return 0;
+ }
+ save_flags(flags);
+ cli();
+ nskb = skb_clone(skb, GFP_ATOMIC);
+ if (nskb) {
+ if (chanp->lc_b.l2_establish) {
+ csta->hs[chanp->hscx].tx_cnt += len + st->l2.ihsize;
+ chanp->ds.l3.l3l2(&chanp->ds, DL_DATA, nskb);
+ } else {
+ csta->hs[chanp->hscx].tx_cnt += len;
+ chanp->ds.l2.l2l1(&chanp->ds, PH_DATA, nskb);
+ }
+ dev_kfree_skb(skb, FREE_WRITE);
+ } else
+ len = 0;
+ restore_flags(flags);
}
+ return (len);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov