working X75 orginating call

This commit is contained in:
Karsten Keil 2001-03-03 08:07:30 +00:00
parent fb3bf581f4
commit d34984bb05
23 changed files with 806 additions and 540 deletions

View File

@ -9,7 +9,6 @@ O_TARGET :=
# EXTRA_CFLAGS += -S -g
# multi objects
SEDLFAXOBJ := sedl_fax.o debug.o helper.o
@ -29,6 +28,11 @@ OBJ_capi := capi.o contr.o listen.o appl.o plci.o cplci.o ncci.o asn1.o \
LX_OBJS += hisax_core.o
ifdef MEMDBG
EXTRA_CFLAGS += -DMEMDBG
MX_OBJS += memdbg.o
endif
#ifeq ($(CONFIG_ISDN_DRV_HISAX),y)
# O_TARGET += hisax.o
#else

View File

@ -22,8 +22,8 @@ static const char *avm_pci_rev = "$Revision$";
#define ISDN_CTYPE_FRITZPCI 1
#define AVM_FRITZ_PCI 1
#define AVM_FRITZ_PNP 2
#define AVM_FRITZ_PCI 1
#define AVM_FRITZ_PNP 2
#ifndef PCI_VENDOR_ID_AVM
#define PCI_VENDOR_ID_AVM 0x1244
@ -773,21 +773,24 @@ static int init_card(fritzpnppci *fc)
{
int irq_cnt, cnt = 3;
long flags;
u_int shared = SA_SHIRQ;
if (fc->subtyp == AVM_FRITZ_PNP)
shared = 0;
save_flags(flags);
irq_cnt = kstat_irqs(fc->irq);
printk(KERN_INFO "AVM Fritz!PCI: IRQ %d count %d\n", fc->irq, irq_cnt);
lock_dev(fc);
if (request_irq(fc->irq, avm_pcipnp_interrupt, SA_SHIRQ,
"AVM Fritz!PCI", fc)) {
printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n",
fc->irq);
unlock_dev(fc);
return(-EIO);
}
save_flags(flags);
while (cnt) {
sti();
current->state = TASK_UNINTERRUPTIBLE;
clear_pending_isac_ints(&fc->dch);
initisac(&fc->dch);
init_isac(&fc->dch);
clear_pending_hdlc_ints(fc);
inithdlc(fc);
outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER,
@ -797,7 +800,10 @@ static int init_card(fritzpnppci *fc)
AVM_STATUS0_ENA_IRQ, fc->addr + 2);
/* RESET Receiver and Transmitter */
WriteISAC(fc, ISAC_CMDR, 0x41);
unlock_dev(fc);
sti();
/* Timeout 10ms */
current->state = TASK_UNINTERRUPTIBLE;
schedule_timeout((10*HZ)/1000);
restore_flags(flags);
printk(KERN_INFO "AVM Fritz!PCI: IRQ %d count %d\n",
@ -807,7 +813,6 @@ static int init_card(fritzpnppci *fc)
"AVM Fritz!PCI: IRQ(%d) getting no interrupts during init %d\n",
fc->irq, 4 - cnt);
if (cnt == 1) {
free_irq(fc->irq, fc);
return (-EIO);
} else {
reset_avmpcipnp(fc);
@ -816,21 +821,12 @@ static int init_card(fritzpnppci *fc)
} else {
return(0);
}
lock_dev(fc);
}
restore_flags(flags);
unlock_dev(fc);
return(-EIO);
}
static void
closecard(fritzpnppci *fc)
{
close_hdlcstate(fc->bch + 1);
close_hdlcstate(fc->bch);
DC_Close_isac(&fc->dch);
outb(0, fc->addr + 2);
release_region(fc->addr, 32);
}
void
BChannel_bh(bchannel_t *bch)
{
@ -1001,13 +997,18 @@ dummy_down(hisaxif_t *hif, u_int prim, u_int nr, int dtyp, void *arg) {
static int
add_if(hisaxinstance_t *inst, int channel, hisaxif_t *hif) {
int err;
int err, lay;
fritzpnppci *card = inst->data;
if (!hif)
return(-EINVAL);
if (IF_TYPE(hif) != IF_UP)
return(-EINVAL);
lay = layermask2layer(hif->layermask);
if (lay < 0) {
int_errtxt("lm %x", hif->layermask);
return(-EINVAL);
}
switch(hif->protocol) {
case ISDN_PID_L1_B_64TRANS:
case ISDN_PID_L1_B_64HDLC:
@ -1016,12 +1017,12 @@ add_if(hisaxinstance_t *inst, int channel, hisaxif_t *hif) {
return(-EINVAL);
hif->fdata = &card->bch[channel];
hif->func = hdlc_down;
inst->protocol = hif->protocol;
inst->pid.protocol[lay] = hif->protocol;
if (inst->up.stat == IF_NOACTIV) {
printk(KERN_DEBUG "fritz_add_if set upif\n");
inst->up.stat = IF_DOWN;
inst->up.layer = hif->inst->layer;
inst->up.protocol = hif->inst->protocol;
inst->up.layermask = get_up_layer(inst->layermask);
inst->up.protocol = get_protocol(inst->st, inst->up.layermask);
err = fritz.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->up);
if (err) {
printk(KERN_WARNING "fritz_add_if up no if\n");
@ -1036,8 +1037,8 @@ add_if(hisaxinstance_t *inst, int channel, hisaxif_t *hif) {
hif->func = ISAC_l1hw;
if (inst->up.stat == IF_NOACTIV) {
inst->up.stat = IF_DOWN;
inst->up.protocol =
inst->st->protocols[inst->up.layer];
inst->up.layermask = get_up_layer(inst->layermask);
inst->up.protocol = get_protocol(inst->st, inst->up.layermask);
err = fritz.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->up);
if (err)
inst->up.stat = IF_NOACTIV;
@ -1056,7 +1057,7 @@ del_if(hisaxinstance_t *inst, int channel, hisaxif_t *hif) {
int err;
fritzpnppci *card = inst->data;
printk(KERN_DEBUG "fritz del_if lay %d/%d %p/%p\n", hif->layer,
printk(KERN_DEBUG "fritz del_if lay %x/%x %p/%p\n", hif->layermask,
hif->stat, hif->func, hif->fdata);
if ((hif->func == inst->up.func) && (hif->fdata == inst->up.fdata)) {
if (channel==2)
@ -1076,14 +1077,18 @@ del_if(hisaxinstance_t *inst, int channel, hisaxif_t *hif) {
static void
release_card(fritzpnppci *card) {
closecard(card);
lock_dev(card);
outb(0, card->addr + 2);
free_irq(card->irq, card);
if (card->next)
card->next->prev = card->prev;
if (card->prev)
card->prev->next = card->next;
if (card == cardlist)
cardlist = card->next;
close_hdlcstate(card->bch + 1);
close_hdlcstate(card->bch);
free_isac(&card->dch);
release_region(card->addr, 32);
free_bchannel(&card->bch[1]);
free_bchannel(&card->bch[0]);
free_dchannel(&card->dch);
REMOVE_FROM_LISTBASE(card, cardlist);
unlock_dev(card);
kfree(card);
fritz.refcnt--;
}
@ -1092,25 +1097,28 @@ static int
set_stack(hisaxstack_t *st, hisaxinstance_t *inst, int chan, hisax_pid_t *pid) {
int err,layer = 0;
#if 0
if (st->inst[0] || st->inst[1] || st->inst[2]) {
return(-EBUSY);
}
if (!HasProtocol(inst, pid->B1)) {
#endif
if (!HasProtocol(inst, pid->protocol[1])) {
return(-EPROTONOSUPPORT);
} else
layer = 1;
if (HasProtocol(inst, pid->B2))
layer = 2;
if (HasProtocol(inst, pid->B3))
layer = 3;
inst->layer = layer;
inst->protocol = pid->B1;
layer = ISDN_LAYER(1);
if (HasProtocol(inst, pid->protocol[2])) {
layer |= ISDN_LAYER(2);
if (HasProtocol(inst, protocol[3]))
layer |= ISDN_LAYER(3);
}
inst->layermask = layer;
inst->pid.protocol[1] = pid->protocol[1];
if ((err = fritz.ctrl(st, MGR_ADDLAYER | REQUEST, inst))) {
printk(KERN_WARNING "set_stack MGR_ADDLAYER err(%d)\n", err);
return(err);
}
inst->up.layer = layer + 1;
inst->up.protocol = st->protocols[layer+1];
inst->up.layermask = get_up_layer(layer);
inst->up.protocol = get_protocol(st, inst->up.layermask);
inst->up.inst = inst;
inst->up.stat = IF_DOWN;
if ((err = fritz.ctrl(st, MGR_ADDIF | REQUEST, &inst->up))) {
@ -1124,7 +1132,7 @@ static int
fritz_manager(void *data, u_int prim, void *arg) {
fritzpnppci *card = cardlist;
hisaxinstance_t *inst=NULL;
int i,channel = -1;
int channel = -1;
hisaxstack_t *st = data;
if (!data) {
@ -1163,6 +1171,7 @@ fritz_manager(void *data, u_int prim, void *arg) {
return(-ENODEV);
}
if (channel == 2) {
#if 0
card->dch.inst.st->protocols[0] = ISDN_PID_L0_TE_S0;
card->dch.inst.st->protocols[1] = ISDN_PID_L1_TE_S0;
card->dch.inst.st->protocols[2] = ISDN_PID_L2_LAPD;
@ -1173,6 +1182,7 @@ fritz_manager(void *data, u_int prim, void *arg) {
card->dch.inst.st->protocols[3] = ISDN_PID_NONE;
card->dch.inst.st->protocols[4] = ISDN_PID_NONE;
}
#endif
} else {
break;
}
@ -1237,7 +1247,7 @@ Fritz_init(void)
fritz.name = FritzName;
fritz.own_ctrl = fritz_manager;
fritz.layer = 0;
fritz.layermask = ISDN_LAYER(0);
fritz.protocols = FritzProtocols;
fritz.protcnt = FRITZPCNT;
fritz.prev = NULL;
@ -1260,8 +1270,8 @@ Fritz_init(void)
card->dch.inst.lock = lock_dev;
card->dch.inst.unlock = unlock_dev;
card->dch.inst.data = card;
card->dch.inst.layer = 0;
card->dch.inst.protocol = ISDN_PID_L0_TE_S0;
card->dch.inst.layermask = ISDN_LAYER(0);
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_TE_S0;
card->dch.inst.up.inst = &card->dch.inst;
act_protocol = protocol[fritz_cnt];
sprintf(card->dch.inst.id, "Fritz%d", fritz_cnt+1);
@ -1269,8 +1279,8 @@ Fritz_init(void)
for (i=0; i<2; i++) {
card->bch[i].inst.obj = &fritz;
card->bch[i].inst.data = card;
card->bch[i].inst.layer = 0;
card->bch[i].inst.up.layer = 1;
card->bch[i].inst.layermask = ISDN_LAYER(0);
card->bch[i].inst.up.layermask = ISDN_LAYER(1);
card->bch[i].inst.up.inst = &card->bch[i].inst;
card->bch[i].inst.lock = lock_dev;
card->bch[i].inst.unlock = unlock_dev;
@ -1309,22 +1319,25 @@ Fritz_init(void)
}
if ((err = fritz.ctrl(card->dch.inst.st, MGR_ADDLAYER | REQUEST, &card->dch.inst))) {
printk(KERN_ERR "MGR_ADDLAYER REQUEST dch err(%d)\n", err);
release_card(card);
fritz.ctrl(card->dch.inst.st,
MGR_DELSTACK | REQUEST, NULL);
if (!fritz_cnt)
HiSax_unregister(&fritz);
else
err = 0;
return(err);
}
card->dch.inst.up.layer = 1;
card->dch.inst.up.layermask = get_up_layer(card->dch.inst.layermask);
card->dch.inst.up.stat = IF_DOWN;
card->dch.inst.up.protocol = card->dch.inst.st->protocols[1];
card->dch.inst.up.protocol = get_protocol(card->dch.inst.st,
card->dch.inst.up.layermask);
card->dch.inst.down.func = dummy_down;
card->dch.inst.down.fdata = card;
if ((err = fritz.ctrl(card->dch.inst.st, MGR_ADDIF | REQUEST,
&card->dch.inst.up))) {
printk(KERN_ERR "MGR_ADDIF REQUEST dch err(%d)\n", err);
release_card(card);
fritz.ctrl(card->dch.inst.st,
MGR_DELSTACK | REQUEST, NULL);
if (!fritz_cnt)
HiSax_unregister(&fritz);
else
@ -1335,7 +1348,8 @@ Fritz_init(void)
if ((err = fritz.ctrl(card->dch.inst.st, MGR_ADDSTACK | REQUEST,
&card->bch[i].inst))) {
printk(KERN_ERR "MGR_ADDSTACK bchan error %d\n", err);
release_card(card);
fritz.ctrl(card->dch.inst.st,
MGR_DELSTACK | REQUEST, NULL);
if (!fritz_cnt)
HiSax_unregister(&fritz);
else
@ -1344,7 +1358,7 @@ Fritz_init(void)
}
}
if ((err = init_card(card))) {
release_card(card);
fritz.ctrl(card->dch.inst.st, MGR_DELSTACK | REQUEST, NULL);
if (!fritz_cnt)
HiSax_unregister(&fritz);
else

View File

@ -17,7 +17,9 @@ static hisaxobject_t capi_obj;
static char MName[] = "HiSax Capi 2.0";
static int Capi20Protocols[] = { ISDN_PID_CAPI20
static int Capi20Protocols[] = {ISDN_PID_L4_CAPI20,
ISDN_PID_L4_B_CAPI20,
ISDN_PID_L3_B_TRANS
};
#define PROTOCOLCNT (sizeof(Capi20Protocols)/sizeof(int))
@ -173,7 +175,7 @@ static int
add_if_contr(Contr_t *ctrl, hisaxinstance_t *inst, hisaxif_t *hif) {
int err;
printk(KERN_DEBUG "capi add_if lay %d/%x prot %x\n", hif->layer,
printk(KERN_DEBUG "capi add_if lay %x/%x prot %x\n", hif->layermask,
hif->stat, hif->protocol);
if (IF_TYPE(hif) == IF_UP) {
printk(KERN_WARNING "capi add_if here is no UP interface\n");
@ -187,8 +189,9 @@ add_if_contr(Contr_t *ctrl, hisaxinstance_t *inst, hisaxif_t *hif) {
}
if (inst->down.stat == IF_NOACTIV) {
inst->down.stat = IF_UP;
inst->down.protocol =
inst->st->protocols[inst->down.layer];
inst->down.layermask = get_down_layer(hif->layermask);
inst->down.protocol = get_protocol(inst->st,
inst->down.layermask);
err = capi_obj.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->down);
if (err)
inst->down.stat = IF_NOACTIV;
@ -202,7 +205,7 @@ static int
del_if(hisaxinstance_t *inst, hisaxif_t *hif) {
int err;
printk(KERN_DEBUG "capi del_if lay %d/%x %p/%p\n", hif->layer,
printk(KERN_DEBUG "capi del_if lay %x/%x %p/%p\n", hif->layermask,
hif->stat, hif->func, hif->fdata);
if ((hif->func == inst->up.func) && (hif->fdata == inst->up.fdata)) {
inst->up.stat = IF_NOACTIV;
@ -266,6 +269,21 @@ capi20_manager(void *data, u_int prim, void *arg) {
}
return(del_if(inst, arg));
break;
case MGR_DELLAYER | REQUEST:
if (inst) {
if (ctrl->inst.st == st) {
DelIF(inst, &inst->down, contrL3L4, ctrl);
} else {
hisaxif_t hif;
ncciSetInterface(&hif);
DelIF(inst, &inst->down, hif.func, inst->data);
}
} else {
printk(KERN_WARNING "capi20_manager DELLAYER no instance\n");
return(-EINVAL);
}
capi_obj.ctrl(st, MGR_DELLAYER | REQUEST, inst);
break;
case MGR_RELEASE | INDICATION:
if (ctrl) {
printk(KERN_DEBUG "release_capi20 id %x\n", ctrl->inst.st->id);
@ -291,7 +309,7 @@ int Capi20Init(void)
capi_obj.prev = NULL;
capi_obj.next = NULL;
capi_obj.ilist = NULL;
capi_obj.layer = 4;
capi_obj.layermask = ISDN_LAYER(4);
if ((err = CapiNew()))
return(err);
if ((err = HiSax_register(&capi_obj))) {

View File

@ -15,6 +15,9 @@
#include "../avmb1/capilli.h"
#include "asn1.h"
#include "fsm.h"
#ifdef MEMDBG
#include "memdbg.h"
#endif
// ---------------------------------------------------------------------------
// common stuff

View File

@ -14,7 +14,7 @@
int contrConstr(Contr_t *contr, hisaxstack_t *st, hisaxif_t *hif, hisaxobject_t *ocapi)
{
char tmp[10];
int lay, err;
int err;
hisaxstack_t *cst = st->child;
BInst_t *binst;
@ -32,10 +32,10 @@ int contrConstr(Contr_t *contr, hisaxstack_t *st, hisaxif_t *hif, hisaxobject_t
binst->inst.st = cst;
binst->inst.data = binst;
binst->inst.obj = ocapi;
binst->inst.layer = 4;
binst->inst.layermask = ISDN_LAYER(4);
binst->inst.down.stat = IF_NOACTIV;
binst->inst.down.protocol = ISDN_PID_NONE;
binst->inst.down.layer = 3;
binst->inst.down.layermask = get_down_layer(binst->inst.layermask);
APPEND_TO_LIST(binst, contr->binst);
cst = cst->next;
}
@ -43,20 +43,15 @@ int contrConstr(Contr_t *contr, hisaxstack_t *st, hisaxif_t *hif, hisaxobject_t
contr->ctrl = cdrv_if->attach_ctr(&hisax_driver, tmp, contr);
if (!contr->ctrl)
return -ENODEV;
contr->inst.protocol = hif->protocol;
contr->inst.layer = hif->layer;
contr->inst.pid.protocol[4] = hif->protocol;
contr->inst.layermask = hif->layermask;
contr->inst.data = contr;
ocapi->ctrl(st, MGR_ADDLAYER | INDICATION, &contr->inst);
contr->inst.up.protocol = ISDN_PID_NONE;
contr->inst.up.layer = 0;
contr->inst.up.layermask = 0;
contr->inst.up.stat = IF_DOWN;
lay = contr->inst.layer - 1;
if ((lay<0) || (lay>MAX_LAYER)) {
lay = 0;
contr->inst.down.protocol = ISDN_PID_NONE;
} else
contr->inst.down.protocol = st->protocols[lay];
contr->inst.down.layer = lay;
contr->inst.down.layermask = get_down_layer(contr->inst.layermask);
contr->inst.down.protocol = get_protocol(st, contr->inst.down.layermask);
contr->inst.down.stat = IF_UP;
err = ocapi->ctrl(st, MGR_ADDIF | REQUEST, &contr->inst.down);
if (err) {
@ -288,6 +283,7 @@ void contrDelPlci(Contr_t *contr, Plci_t *plci)
{
int i = plci->adrPLCI >> 8;
contrDebug(contr, LL_DEB_INFO, __FUNCTION__ ": PLCI(%x)", plci->adrPLCI);
if ((i < 1) || (i > CAPI_MAXPLCI)) {
int_error();
return;
@ -407,10 +403,10 @@ BInst_t *contrSelChannel(Contr_t *contr, int channr)
binst->inst.st = cst;
binst->inst.data = binst;
binst->inst.obj = contr->inst.obj;
binst->inst.layer = 4;
binst->inst.layermask = ISDN_LAYER(4);
binst->inst.down.stat = IF_NOACTIV;
binst->inst.down.protocol = ISDN_PID_NONE;
binst->inst.down.layer = 3;
binst->inst.down.layermask = get_down_layer(binst->inst.layermask);
APPEND_TO_LIST(binst, contr->binst);
cst = cst->next;
}

View File

@ -41,7 +41,7 @@ find_object(int layer, int protocol) {
int i, *pp;
while (obj) {
if (obj->layer == layer) {
if (obj->layermask & layer) {
pp = obj->protocols;
for (i=0; i<obj->protcnt; i++) {
if (*pp == protocol)
@ -60,7 +60,7 @@ find_object_module(int layer, int protocol) {
hisaxobject_t *obj;
while (m->name != NULL) {
if (m->layer == layer) {
if (m->layermask & layer) {
if (m->protocol == protocol) {
#ifdef CONFIG_KMOD
if (debug)
@ -84,52 +84,16 @@ find_object_module(int layer, int protocol) {
return(NULL);
}
static int
register_instance(hisaxstack_t *st, hisaxinstance_t *inst) {
int lay;
if (!st || !inst)
return(-EINVAL);
lay = inst->layer;
if (debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "register_instance st(%p) inst(%p) lay(%d)\n",
st, inst, lay);
if ((lay>MAX_LAYER) || (lay<0))
return(-EINVAL);
APPEND_TO_LIST(inst, st->inst[lay]);
st->protocols[lay] = inst->protocol;
inst->st = st;
inst->obj->refcnt++;
return(0);
}
static int
unregister_instance(hisaxstack_t *st, hisaxinstance_t *inst) {
int lay;
if (!st || !inst)
return(-EINVAL);
lay = inst->layer;
if (debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "unregister_instance st(%p) inst(%p) lay(%d)\n",
st, inst, lay);
if ((lay>MAX_LAYER) || (lay<0))
return(-EINVAL);
REMOVE_FROM_LISTBASE(inst, st->inst[lay]);
st->protocols[lay] = ISDN_PID_NONE;
inst->obj->refcnt--;
return(0);
}
static void
remove_object(hisaxobject_t *obj) {
hisaxstack_t *st = hisax_stacklist;
hisaxlayer_t *layer;
hisaxinstance_t *inst, *tmp;
int l;
while (st) {
for(l=0;l<=MAX_LAYER;l++) {
inst = st->inst[l];
layer = st->lstack;
while(layer) {
inst = layer->inst;
while (inst) {
if (inst->obj == obj) {
tmp = inst->next;
@ -139,6 +103,7 @@ remove_object(hisaxobject_t *obj) {
} else
inst = inst->next;
}
layer = layer->next;
}
st = st->next;
}
@ -160,12 +125,10 @@ add_stack_if(hisaxstack_t *st, hisaxif_t *hif) {
if (!hif)
return(-EINVAL);
lay = hif->layer;
lay = layermask2layer(hif->layermask);
if (debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "add_stack_if for layer %d proto %x/%x\n",
lay, hif->protocol, hif->stat);
if ((lay>MAX_LAYER) || (lay<0))
return(-EINVAL);
if (hif->protocol == ISDN_PID_NONE) {
printk(KERN_WARNING "add_stack_if: for protocol none\n");
hif->fdata = NULL;
@ -173,16 +136,17 @@ add_stack_if(hisaxstack_t *st, hisaxif_t *hif) {
hif->stat = IF_NOACTIV;
return(0);
}
inst = st->inst[lay];
while(inst) {
if (inst->protocol == hif->protocol)
obj = inst->obj;
inst = inst->next;
if (lay<0) {
int_errtxt("lm %x", hif->layermask);
return(-EINVAL);
}
inst = get_instance(st, lay, hif->protocol);
if (inst)
obj = inst->obj;
if (!obj)
obj = find_object(lay, hif->protocol);
obj = find_object(hif->layermask, hif->protocol);
if (!obj)
obj = find_object_module(lay, hif->protocol);
obj = find_object_module(hif->layermask, hif->protocol);
if (!obj) {
printk(KERN_WARNING "add_stack_if: no object found\n");
return(-ENOPROTOOPT);
@ -201,15 +165,20 @@ del_stack_if(hisaxstack_t *st, hisaxif_t *hif) {
if (!hif)
return(-EINVAL);
lay = hif->layer;
lay = layermask2layer(hif->layermask);
if (debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "del_stack_if for layer %d proto %x/%x\n",
lay, hif->protocol, hif->stat);
if ((lay>MAX_LAYER) || (lay<0))
if (lay<0) {
int_errtxt("lm %x", hif->layermask);
return(-EINVAL);
inst = st->inst[lay];
}
if (!(inst = get_instance(st, lay, hif->protocol))) {
printk(KERN_DEBUG "del_stack_if no instance found\n");
return(-ENODEV);
}
while(inst) {
if (inst->protocol == hif->protocol) {
if (inst->pid.protocol[lay] == hif->protocol) {
obj = inst->obj;
err = obj->own_ctrl(st, MGR_DELIF | REQUEST, hif);
if (err)
@ -260,15 +229,17 @@ static int central_manager(void *data, u_int prim, void *arg) {
return(set_stack(st, arg));
case MGR_CLEARSTACK | REQUEST:
return(clear_stack(st));
case MGR_DELSTACK | REQUEST:
return(release_stack(st));
case MGR_ADDLAYER | INDICATION:
return(register_instance(st, arg));
return(register_layer(st, arg));
case MGR_ADDLAYER | REQUEST:
if (!register_instance(st, arg)) {
if (!register_layer(st, arg)) {
hisaxinstance_t *inst = arg;
return(inst->obj->own_ctrl(st, MGR_ADDLAYER | CONFIRM, arg));
}
case MGR_DELLAYER | REQUEST:
return(unregister_instance(st, arg));
return(unregister_instance(arg));
case MGR_ADDIF | REQUEST:
return(add_stack_if(st, arg));
case MGR_DELIF | REQUEST:
@ -319,7 +290,7 @@ int HiSax_unregister(hisaxobject_t *obj) {
if (debug)
printk(KERN_DEBUG "HiSax_unregister %s %d refs\n",
obj->name, obj->refcnt);
if (obj->layer == 0)
if (obj->layermask == ISDN_LAYER(0))
release_stacks(obj);
else
remove_object(obj);
@ -339,6 +310,7 @@ HiSaxInit(void)
#ifdef MODULE
void cleanup_module(void) {
hisaxstack_t *st;
free_hisaxdev();
if (hisax_objects) {
@ -346,6 +318,16 @@ void cleanup_module(void) {
}
if (hisax_stacklist) {
printk(KERN_WARNING "hisaxcore hisax_stacklist not empty\n");
st = hisax_stacklist;
while (st) {
printk(KERN_WARNING "hisaxcore st %x in list\n",
st->id);
if (st == st->next) {
printk(KERN_WARNING "hisaxcore st == next\n");
break;
}
st = st->next;
}
}
printk(KERN_DEBUG "hisaxcore unloaded\n");
}

View File

@ -8,7 +8,10 @@
#include <linux/string.h>
#include <linux/hisaxif.h>
#include "helper.h"
#ifdef MEMDBG
#include "memdbg.h"
#endif
#define HISAX_MAJOR 46
#define HISAX_DEVBUF_SIZE 8192
@ -33,14 +36,19 @@ extern void get_stack_profile(iframe_t *);
extern int get_stack_cnt(void);
extern hisaxstack_t *get_stack4id(int);
extern hisaxstack_t *new_stack(hisaxinstance_t *, hisaxstack_t *);
extern int release_stack(hisaxstack_t *);
extern void release_stacks(hisaxobject_t *);
extern int set_stack(hisaxstack_t *, hisax_pid_t *);
extern int clear_stack(hisaxstack_t *);
extern hisaxlayer_t *getlayer4lay(hisaxstack_t *, int);
extern hisaxinstance_t *get_instance(hisaxstack_t *, int, int);
/* from hisax_core.c */
extern hisaxobject_t *hisax_objects;
extern int core_debug;
extern void hisaxlock_core(void);
extern void hisaxunlock_core(void);
extern void hisaxlock_core(void);
extern void hisaxunlock_core(void);
extern int register_layer(hisaxstack_t *, hisaxinstance_t *);
extern int unregister_instance(hisaxinstance_t *);

View File

@ -129,36 +129,27 @@ free_bchannel(bchannel_t *bch) {
}
int bprotocol2pid(void *bp, hisax_pid_t *pid) {
__u8 *p = bp;
__u16 *w = bp;
__u8 *p = bp;
__u16 *w = bp;
int i;
p += 6;
pid->B1 = *w;
pid->B1 |= ISDN_PID_LAYER1 | ISDN_PID_BCHANNEL_BIT;
if (*p)
pid->B1p = p;
else
pid->B1p = NULL;
w++;
p += *p;
p++;
pid->B2 = *w;
pid->B2 |= ISDN_PID_LAYER2 | ISDN_PID_BCHANNEL_BIT;
if (*p)
pid->B2p = p;
else
pid->B2p = NULL;
w++;
p += *p;
p++;
pid->B3 = *w;
pid->B3 |= ISDN_PID_LAYER3 | ISDN_PID_BCHANNEL_BIT;
if (*p)
pid->B3p = p;
else
pid->B3p = NULL;
p += *p;
p++;
for (i=1; i<=3; i++) {
if (*w > 23) {
int_errtxt("L%d pid %x\n",i,*w);
return(-EINVAL);
}
pid->protocol[i] = (1 <<*w) | ISDN_PID_LAYER(i) |
ISDN_PID_BCHANNEL_BIT;
if (*p)
pid->param[i] = p;
else
pid->param[i] = NULL;
w++;
p += *p;
p++;
}
if (*p)
pid->global = p;
else
@ -180,15 +171,87 @@ int HasProtocol(hisaxinstance_t *inst, int proto) {
return(0);
}
int
layermask2layer(int layermask) {
switch(layermask) {
case ISDN_LAYER(0): return(0);
case ISDN_LAYER(1): return(1);
case ISDN_LAYER(2): return(2);
case ISDN_LAYER(3): return(3);
case ISDN_LAYER(4): return(4);
case ISDN_LAYER(5): return(5);
case ISDN_LAYER(6): return(6);
case ISDN_LAYER(7): return(7);
case 0: return(-1);
}
return(-2);
}
int
get_protocol(hisaxstack_t *st, int layermask)
{
int layer = layermask2layer(layermask);
if (!st){
int_error();
return(-EINVAL);
}
if (layer<0) {
int_errtxt("lmask(%x) layer(%x) st(%x)",
layermask, layer, st->id);
return(-EINVAL);
}
return(st->pid.protocol[layer]);
}
int get_down_layer(int layermask) {
int downlayer = 2;
if (layermask>255 || (layermask & 1)) {
int_errtxt("lmask %x out of range", layermask);
return(0);
}
while(downlayer & 0xFF) {
if (downlayer & layermask)
break;
downlayer <<= 1;
}
if (downlayer & 0xFF)
downlayer >>= 1;
else
downlayer = 0;
return(downlayer);
}
int get_up_layer(int layermask) {
int uplayer = 0x40;
if (layermask>=128) {
int_errtxt("lmask %x out of range", layermask);
return(0);
}
while(uplayer) {
if (uplayer & layermask)
break;
uplayer >>= 1;
}
if (uplayer)
uplayer <<= 1;
else
uplayer = 1;
return(uplayer);
}
int DelIF(hisaxinstance_t *inst, hisaxif_t *mif, void *func, void *data) {
hisaxif_t hif;
memset(&hif, 0, sizeof(hisaxif_t));
hif.protocol = mif->protocol;
hif.layer = mif->layer;
hif.layermask = mif->layermask;
hif.fdata = data;
hif.func = func;
hif.func(&hif, MGR_DELIF | REQUEST, 0, 0, NULL);
mif->protocol = ISDN_PID_NONE;
mif->stat = IF_NOACTIV;
inst->obj->ctrl(inst->st, MGR_ADDIF | REQUEST, mif);
return(inst->obj->ctrl(inst->st, MGR_DELIF | REQUEST, &hif));
}

View File

@ -7,11 +7,18 @@
*/
#include <linux/kernel.h>
#include <linux/skbuff.h>
#ifdef MEMDBG
#include "memdbg.h"
#endif
#define int_error() \
printk(KERN_ERR "hisax: INTERNAL ERROR in %s:%d\n", \
__FILE__, __LINE__)
#define int_errtxt(fmt, arg...) \
printk(KERN_ERR "hisax: INTERNAL ERROR in %s:%d " fmt "\n", \
__FILE__, __LINE__, ## arg)
#define APPEND_TO_LIST(item,base) \
item->prev = base; \
while (item->prev && item->prev->next) \
@ -33,3 +40,6 @@
base = item->next
extern int discard_queue(struct sk_buff_head *);
extern int get_up_layer(int);
extern int get_down_layer(int);
extern int layermask2layer(int);

View File

@ -15,6 +15,9 @@
#include <asm/io.h>
#include <linux/ioport.h>
#include <linux/skbuff.h>
#ifdef MEMDBG
#include "memdbg.h"
#endif
#define MAX_DFRAME_LEN_L1 300
#define MAX_MON_FRAME 32

View File

@ -800,6 +800,7 @@ send_frames(bchannel_t *bch)
}
}
}
bch->hw.isar.txcnt = 0;
if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flag)) {
if (bch->next_skb) {
bch->tx_len = bch->next_skb->len;
@ -1408,13 +1409,13 @@ setup_iom2(bchannel_t *bch) {
udelay(1000);
}
int
modeisar(bchannel_t *bch, bsetup_t *bs)
static int
modeisar(bchannel_t *bch, int channel, u_int bprotocol, u_char *param)
{
/* Here we are selecting the best datapath for requested protocol */
if(bch->protocol == ISDN_PID_NONE) { /* New Setup */
bch->channel = bs->channel;
switch (bs->protocol[0]) {
bch->channel = channel;
switch (bprotocol) {
case ISDN_PID_NONE: /* init */
if (!bch->hw.isar.dpath)
/* no init for dpath 0 */
@ -1453,8 +1454,8 @@ modeisar(bchannel_t *bch, bsetup_t *bs)
}
if (bch->debug & L1_DEB_HSCX)
debugprint(&bch->inst, "isar dp%d protocol %x->%x ichan %d",
bch->hw.isar.dpath, bch->protocol, bs->protocol[0], bs->channel);
bch->protocol = bs->protocol[0];
bch->hw.isar.dpath, bch->protocol, bprotocol, channel);
bch->protocol = bprotocol;
setup_pump(bch);
setup_iom2(bch);
setup_sart(bch);
@ -1583,11 +1584,9 @@ isar_setup(bchannel_t *bch)
{
u_char msg;
int i;
bsetup_t bs;
/* Dpath 1, 2 */
msg = 61;
memset(&bs, 0, sizeof(bsetup_t));
for (i=0; i<2; i++) {
/* Buffer Config */
sendmsg(bch, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) |
@ -1595,8 +1594,7 @@ isar_setup(bchannel_t *bch)
bch[i].hw.isar.mml = msg;
bch[i].protocol = 0;
bch[i].hw.isar.dpath = i + 1;
bs.channel = i;
modeisar(&bch[i], &bs);
modeisar(&bch[i], i, 0, NULL);
}
}
@ -1607,7 +1605,7 @@ isar_down(hisaxif_t *hif, u_int prim, u_int nr, int len, void *arg)
int ret = 0;
if ((prim == PH_DATA_REQ) ||
(prim == (CC_B3_DATA | REQUEST))) {
(prim == (DL_DATA | REQUEST))) {
struct sk_buff *skb = arg;
if (bch->next_skb) {
@ -1629,38 +1627,34 @@ isar_down(hisaxif_t *hif, u_int prim, u_int nr, int len, void *arg)
bch->inst.up.func(&bch->inst.up, PH_DATA_CNF, nr,
DTYPE_SKB, skb);
}
} else if (prim == (PH_ACTIVATE | REQUEST)) {
bsetup_t bs;
memset(&bs, 0, sizeof(bsetup_t));
bs.channel = bch->channel;
bs.protocol[0] = bch->inst.protocol;
} else if ((prim == (PH_ACTIVATE | REQUEST)) ||
(prim == (DL_ESTABLISH | REQUEST))) {
test_and_set_bit(BC_FLG_ACTIV, &bch->Flag);
bch->inst.lock(bch->inst.data);
ret = modeisar(bch, &bs);
ret = modeisar(bch, bch->channel,
bch->inst.pid.protocol[1], NULL);
bch->inst.unlock(bch->inst.data);
if (ret)
bch->inst.up.func(&bch->inst.up, PH_ACTIVATE | CONFIRM, nr,
bch->inst.up.func(&bch->inst.up, prim | CONFIRM, nr,
ret, NULL);
else
bch->inst.up.func(&bch->inst.up, PH_ACTIVATE | CONFIRM, nr,
bch->inst.up.func(&bch->inst.up, prim | CONFIRM, nr,
0, NULL);
} else if (prim == (PH_DEACTIVATE | REQUEST)) {
bsetup_t bs;
memset(&bs, 0, sizeof(bsetup_t));
bs.channel = bch->channel;
} else if ((prim == (PH_DEACTIVATE | REQUEST)) ||
(prim == (DL_RELEASE | REQUEST)) ||
(prim == (MGR_DELIF | REQUEST))) {
bch->inst.lock(bch->inst.data);
if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flag)) {
dev_kfree_skb(bch->next_skb);
bch->next_skb = NULL;
}
test_and_clear_bit(FLG_TX_BUSY, &bch->Flag);
modeisar(bch, &bs);
modeisar(bch, bch->channel, 0, NULL);
test_and_clear_bit(BC_FLG_ACTIV, &bch->Flag);
bch->inst.unlock(bch->inst.data);
bch->inst.up.func(&bch->inst.up, PH_DEACTIVATE | CONFIRM, nr++,
0, NULL);
if (prim != (MGR_DELIF | REQUEST))
bch->inst.up.func(&bch->inst.up, prim | CONFIRM, nr++,
0, NULL);
} else if (prim == (PH_CONTROL | REQUEST)) {
int *val = arg;
int len;
@ -1710,6 +1704,9 @@ isar_down(hisaxif_t *hif, u_int prim, u_int nr, int len, void *arg)
bch->inst.up.func(&bch->inst.up, PH_CONTROL | RESPONSE,
nr++, 0, 0);
}
} else {
printk(KERN_WARNING "isar_down unknown prim(%x)\n", prim);
ret = -EINVAL;
}
return(ret);
}
@ -1781,11 +1778,7 @@ isar_auxcmd(bchannel_t *bch, isdn_ctrl *ic) {
void
free_isar(bchannel_t *bch)
{
bsetup_t bs;
memset(&bs, 0, sizeof(bsetup_t));
bs.channel = bch->channel;
modeisar(bch, &bs);
modeisar(bch, bch->channel, 0, NULL);
del_timer(&bch->hw.isar.ftimer);
}

View File

@ -753,7 +753,7 @@ l3dss1_release_cmpl(l3_process_t *pc, u_char pr, void *arg)
findie(skb->data, skb->len, IE_SIGNAL, 0);
pc->para.RELEASE_COMPLETE.USER_USER =
findie(skb->data, skb->len, IE_USER_USER, 0);
hisax_l3up(pc, CC_RELEASE | CONFIRM, &pc->para.RELEASE_COMPLETE);
hisax_l3up(pc, CC_RELEASE_COMPLETE | INDICATION, &pc->para.RELEASE_COMPLETE);
release_l3_process(pc);
}
@ -1331,18 +1331,18 @@ l3dss1_release_ind(l3_process_t *pc, u_char pr, void *arg)
/* ETS 300-104 7.6.1, 8.6.1, 10.6.1... and 16.1
* set down layer 3 without sending any message
*/
hisax_l3up(pc, CC_RELEASE | INDICATION, pc);
hisax_l3up(pc, CC_RELEASE | INDICATION, NULL);
newl3state(pc, 0);
release_l3_process(pc);
} else {
hisax_l3up(pc, CC_RELEASE | INDICATION, pc);
hisax_l3up(pc, CC_RELEASE | INDICATION, NULL);
}
}
static void
l3dss1_restart(l3_process_t *pc, u_char pr, void *arg) {
L3DelTimer(&pc->timer);
hisax_l3up(pc, CC_RELEASE | INDICATION, pc);
hisax_l3up(pc, CC_RELEASE | INDICATION, NULL);
release_l3_process(pc);
}
@ -2176,26 +2176,22 @@ release_udss1(layer3_t *l3)
hif.fdata = l3;
hif.func = dss1_fromup;
hif.protocol = inst->up.protocol;
hif.layer = inst->up.layer;
hif.layermask = inst->up.layermask;
u_dss1.ctrl(inst->st, MGR_DELIF | REQUEST, &hif);
hif.fdata = l3;
hif.func = dss1_fromdown;
hif.protocol = inst->down.protocol;
hif.layer = inst->down.layer;
hif.layermask = inst->down.layermask;
u_dss1.ctrl(inst->st, MGR_DELIF | REQUEST, &hif);
REMOVE_FROM_LISTBASE(l3, dss1list);
REMOVE_FROM_LIST(inst);
if (inst->st)
if (inst->st->inst[inst->layer] == inst)
inst->st->inst[inst->layer] = inst->next;
u_dss1.ctrl(inst->st, MGR_DELLAYER | REQUEST, inst);
kfree(l3);
u_dss1.refcnt--;
}
static layer3_t *
create_udss1(hisaxstack_t *st, hisaxif_t *hif) {
layer3_t *nl3;
int lay, err;
int err, lay;
if (!hif)
return(NULL);
@ -2204,6 +2200,11 @@ create_udss1(hisaxstack_t *st, hisaxif_t *hif) {
printk(KERN_ERR "create_udss1 no stack\n");
return(NULL);
}
lay = layermask2layer(hif->layermask);
if (lay < 0) {
int_errtxt("lm %x", hif->layermask);
return(NULL);
}
if (!(nl3 = kmalloc(sizeof(layer3_t), GFP_ATOMIC))) {
printk(KERN_ERR "kmalloc layer3 failed\n");
return(NULL);
@ -2211,12 +2212,14 @@ create_udss1(hisaxstack_t *st, hisaxif_t *hif) {
memset(nl3, 0, sizeof(layer3_t));
nl3->debug = debug;
if (hif->protocol != ISDN_PID_L3_DSS1USER) {
printk(KERN_ERR "udss1 create failed prt %x\n",nl3->inst.protocol);
printk(KERN_ERR "udss1 create failed prt %x\n",hif->protocol);
kfree(nl3);
return(NULL);
}
init_l3(nl3);
if (!(nl3->global = kmalloc(sizeof(l3_process_t), GFP_ATOMIC))) {
printk(KERN_ERR "HiSax can't get memory for dss1 global CR\n");
release_l3(nl3);
kfree(nl3);
return(NULL);
} else {
@ -2229,7 +2232,7 @@ create_udss1(hisaxstack_t *st, hisaxif_t *hif) {
}
if (!(nl3->dummy = kmalloc(sizeof(l3_process_t), GFP_ATOMIC))) {
printk(KERN_ERR "HiSax can't get memory for dss1 dummy CR\n");
kfree(nl3->global);
release_l3(nl3);
kfree(nl3);
return(NULL);
} else {
@ -2240,29 +2243,18 @@ create_udss1(hisaxstack_t *st, hisaxif_t *hif) {
nl3->dummy->l3 = nl3;
L3InitTimer(nl3->dummy, &nl3->dummy->timer);
}
nl3->inst.protocol = hif->protocol;
nl3->inst.pid.protocol[lay] = hif->protocol;
nl3->inst.obj = &u_dss1;
nl3->inst.layer = hif->layer;
nl3->inst.layermask = hif->layermask;
nl3->inst.data = nl3;
init_l3(nl3);
nl3->p_mgr = dss1man;
APPEND_TO_LIST(nl3, dss1list);
u_dss1.ctrl(st, MGR_ADDLAYER | INDICATION, &nl3->inst);
lay = nl3->inst.layer + 1;
if ((lay<0) || (lay>MAX_LAYER)) {
lay = 0;
nl3->inst.up.protocol = ISDN_PID_NONE;
} else
nl3->inst.up.protocol = st->protocols[lay];
nl3->inst.up.layer = lay;
nl3->inst.up.layermask = get_up_layer(nl3->inst.layermask);
nl3->inst.up.protocol = get_protocol(st, nl3->inst.up.layermask);
nl3->inst.up.stat = IF_DOWN;
lay = nl3->inst.layer - 1;
if ((lay<0) || (lay>MAX_LAYER)) {
lay = 0;
nl3->inst.down.protocol = ISDN_PID_NONE;
} else
nl3->inst.down.protocol = st->protocols[lay];
nl3->inst.down.layer = lay;
nl3->inst.down.layermask = get_down_layer(nl3->inst.layermask);
nl3->inst.down.protocol = get_protocol(st, nl3->inst.down.layermask);
nl3->inst.down.stat = IF_UP;
err = u_dss1.ctrl(st, MGR_ADDIF | REQUEST, &nl3->inst.down);
if (err) {
@ -2284,15 +2276,14 @@ add_if(layer3_t *l3, hisaxif_t *hif) {
int err;
hisaxinstance_t *inst = &l3->inst;
printk(KERN_DEBUG "layer3 add_if lay %d/%x prot %x\n", hif->layer,
printk(KERN_DEBUG "layer3 add_if lay %x/%x prot %x\n", hif->layermask,
hif->stat, hif->protocol);
hif->fdata = l3;
if (IF_TYPE(hif) == IF_UP) {
hif->func = dss1_fromup;
if (inst->up.stat == IF_NOACTIV) {
inst->up.stat = IF_DOWN;
inst->up.protocol =
inst->st->protocols[inst->up.layer];
inst->up.protocol = get_protocol(inst->st, inst->up.layermask);
err = u_dss1.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->up);
if (err)
inst->up.stat = IF_NOACTIV;
@ -2301,8 +2292,7 @@ add_if(layer3_t *l3, hisaxif_t *hif) {
hif->func = dss1_fromdown;
if (inst->down.stat == IF_NOACTIV) {
inst->down.stat = IF_UP;
inst->down.protocol =
inst->st->protocols[inst->down.layer];
inst->down.protocol = get_protocol(inst->st, inst->down.layermask);
err = u_dss1.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->down);
if (err)
inst->down.stat = IF_NOACTIV;
@ -2317,7 +2307,7 @@ del_if(layer3_t *l3, hisaxif_t *hif) {
int err;
hisaxinstance_t *inst = &l3->inst;
printk(KERN_DEBUG "layer3 del_if lay %d/%x %p/%p\n", hif->layer,
printk(KERN_DEBUG "layer3 del_if lay %x/%x %p/%p\n", hif->layermask,
hif->stat, hif->func, hif->fdata);
if ((hif->func == inst->up.func) && (hif->fdata == inst->up.fdata)) {
inst->up.stat = IF_NOACTIV;
@ -2377,6 +2367,7 @@ udss1_manager(void *data, u_int prim, void *arg) {
return(del_if(l3l, arg));
break;
case MGR_RELEASE | INDICATION:
case MGR_DELLAYER | REQUEST:
if (l3l) {
printk(KERN_DEBUG "release_udss1 id %x\n", l3l->inst.st->id);
release_udss1(l3l);
@ -2404,7 +2395,7 @@ int UDSS1Init(void)
u_dss1.own_ctrl = udss1_manager;
u_dss1.prev = NULL;
u_dss1.next = NULL;
u_dss1.layer = 3;
u_dss1.layermask = ISDN_LAYER(3);
HiSaxl3New();
if ((err = HiSax_register(&u_dss1))) {
printk(KERN_ERR "Can't register %s error(%d)\n", MName, err);

View File

@ -14,8 +14,8 @@ const char *l1_revision = "$Revision$";
#include <linux/config.h>
#include <linux/module.h>
#include "hisaxl1.h"
#include "helper.h"
#include "hisaxl1.h"
#include "debug.h"
typedef struct _layer1 {
@ -584,26 +584,22 @@ release_l1(layer1_t *l1) {
hif.fdata = l1;
hif.func = l1from_up;
hif.protocol = inst->up.protocol;
hif.layer = inst->up.layer;
hif.layermask = inst->up.layermask;
isdnl1.ctrl(inst->st, MGR_DELIF | REQUEST, &hif);
hif.fdata = l1;
hif.func = l1from_down;
hif.protocol = inst->down.protocol;
hif.layer = inst->down.layer;
hif.layermask = inst->down.layermask;
isdnl1.ctrl(inst->st, MGR_DELIF | REQUEST, &hif);
REMOVE_FROM_LISTBASE(l1, l1list);
REMOVE_FROM_LIST(inst);
if (inst->st)
if (inst->st->inst[inst->layer] == inst)
inst->st->inst[inst->layer] = inst->next;
isdnl1.ctrl(inst->st, MGR_DELLAYER | REQUEST, inst);
kfree(l1);
isdnl1.refcnt--;
}
static layer1_t *
create_l1(hisaxstack_t *st, hisaxif_t *hif) {
layer1_t *nl1;
int lay, err;
int err, lay;
if (!hif)
return(NULL);
@ -612,13 +608,18 @@ create_l1(hisaxstack_t *st, hisaxif_t *hif) {
printk(KERN_ERR "create_l1 no stack\n");
return(NULL);
}
lay = layermask2layer(hif->layermask);
if (lay < 0) {
int_errtxt("lm %x", hif->layermask);
return(NULL);
}
if (!(nl1 = kmalloc(sizeof(layer1_t), GFP_ATOMIC))) {
printk(KERN_ERR "kmalloc layer1_t failed\n");
return(NULL);
}
memset(nl1, 0, sizeof(layer1_t));
nl1->inst.protocol = hif->protocol;
switch(nl1->inst.protocol) {
nl1->inst.pid.protocol[lay] = hif->protocol;
switch(hif->protocol) {
case ISDN_PID_L1_TE_S0:
sprintf(nl1->inst.id, "l1TES0 %d", st->id);
nl1->l1m.fsm = &l1fsm_s;
@ -626,7 +627,7 @@ create_l1(hisaxstack_t *st, hisaxif_t *hif) {
nl1->Flags = 0;
break;
default:
printk(KERN_ERR "layer1 create failed prt %x\n",nl1->inst.protocol);
printk(KERN_ERR "layer1 create failed prt %x\n",hif->protocol);
kfree(nl1);
return(NULL);
}
@ -637,25 +638,15 @@ create_l1(hisaxstack_t *st, hisaxif_t *hif) {
nl1->l1m.printdebug = l1m_debug;
FsmInitTimer(&nl1->l1m, &nl1->timer);
nl1->inst.obj = &isdnl1;
nl1->inst.layer = hif->layer;
nl1->inst.layermask = hif->layermask;
nl1->inst.data = nl1;
APPEND_TO_LIST(nl1, l1list);
isdnl1.ctrl(st, MGR_ADDLAYER | INDICATION, &nl1->inst);
lay = nl1->inst.layer + 1;
if ((lay<0) || (lay>MAX_LAYER)) {
lay = 0;
nl1->inst.up.protocol = ISDN_PID_NONE;
} else
nl1->inst.up.protocol = st->protocols[lay];
nl1->inst.up.layer = lay;
nl1->inst.up.layermask = get_up_layer(nl1->inst.layermask);
nl1->inst.up.protocol = get_protocol(st, nl1->inst.up.layermask);
nl1->inst.up.stat = IF_DOWN;
lay = nl1->inst.layer - 1;
if ((lay<0) || (lay>MAX_LAYER)) {
lay = 0;
nl1->inst.down.protocol = ISDN_PID_NONE;
} else
nl1->inst.down.protocol = st->protocols[lay];
nl1->inst.down.layer = lay;
nl1->inst.down.layermask = get_down_layer(nl1->inst.layermask);
nl1->inst.down.protocol = get_protocol(st, nl1->inst.down.layermask);
nl1->inst.down.stat = IF_UP;
err = isdnl1.ctrl(st, MGR_ADDIF | REQUEST, &nl1->inst.down);
if (err) {
@ -677,15 +668,15 @@ add_if(layer1_t *l1, hisaxif_t *hif) {
int err;
hisaxinstance_t *inst = &l1->inst;
printk(KERN_DEBUG "layer1 add_if lay %d/%x prot %x\n", hif->layer,
printk(KERN_DEBUG "layer1 add_if lay %x/%x prot %x\n", hif->layermask,
hif->stat, hif->protocol);
hif->fdata = l1;
if (IF_TYPE(hif) == IF_UP) {
hif->func = l1from_up;
if (inst->up.stat == IF_NOACTIV) {
inst->up.stat = IF_DOWN;
inst->up.protocol =
inst->st->protocols[inst->up.layer];
inst->up.protocol = get_protocol(inst->st,
inst->up.layermask);
err = isdnl1.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->up);
if (err)
inst->up.stat = IF_NOACTIV;
@ -694,8 +685,8 @@ add_if(layer1_t *l1, hisaxif_t *hif) {
hif->func = l1from_down;
if (inst->down.stat == IF_NOACTIV) {
inst->down.stat = IF_UP;
inst->down.protocol =
inst->st->protocols[inst->down.layer];
inst->down.protocol = get_protocol(inst->st,
inst->down.layermask);
err = isdnl1.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->down);
if (err)
inst->down.stat = IF_NOACTIV;
@ -710,7 +701,7 @@ del_if(layer1_t *l1, hisaxif_t *hif) {
int err;
hisaxinstance_t *inst = &l1->inst;
printk(KERN_DEBUG "layer1 del_if lay %d/%x %p/%p\n", hif->layer,
printk(KERN_DEBUG "layer1 del_if lay %x/%x %p/%p\n", hif->layermask,
hif->stat, hif->func, hif->fdata);
if ((hif->func == inst->up.func) && (hif->fdata == inst->up.fdata)) {
inst->up.stat = IF_NOACTIV;
@ -772,6 +763,7 @@ l1_manager(void *data, u_int prim, void *arg) {
}
return(del_if(l1l, arg));
break;
case MGR_DELLAYER | REQUEST:
case MGR_RELEASE | INDICATION:
if (l1l) {
printk(KERN_DEBUG "release_l1 id %x\n", l1l->inst.st->id);
@ -779,7 +771,6 @@ l1_manager(void *data, u_int prim, void *arg) {
} else
printk(KERN_WARNING "l1_manager release no instance\n");
break;
default:
printk(KERN_WARNING "l1_manager prim %x not handled\n", prim);
return(-EINVAL);
@ -797,7 +788,7 @@ int Isdnl1Init(void)
isdnl1.own_ctrl = l1_manager;
isdnl1.prev = NULL;
isdnl1.next = NULL;
isdnl1.layer = 1;
isdnl1.layermask = ISDN_LAYER(1);
#ifdef HISAX_UINTERFACE
l1fsm_u.state_count = L1U_STATE_COUNT;
l1fsm_u.event_count = L1_EVENT_COUNT;

View File

@ -8,6 +8,9 @@
#include <linux/hisaxif.h>
#include "fsm.h"
#ifdef MEMDBG
#include "memdbg.h"
#endif
#define D_RCVBUFREADY 0
#define D_XMTBUFREADY 1

View File

@ -1761,6 +1761,7 @@ l2from_down(hisaxif_t *hif, u_int prim, u_int nr, int dtyp, void *arg) {
int ret = -EINVAL;
int *iarg;
printk(KERN_DEBUG __FUNCTION__ ": prim(%x)\n", prim);
if (!hif)
return(-EINVAL);
l2 = hif->fdata;
@ -1813,7 +1814,7 @@ l2from_down(hisaxif_t *hif, u_int prim, u_int nr, int dtyp, void *arg) {
}
break;
default:
l2m_debug(&l2->l2m, "l2 unknown pr %04x", prim);
l2m_debug(&l2->l2m, "l2 unknown pr %x", prim);
ret = -EINVAL;
break;
}
@ -1826,6 +1827,7 @@ static int
l2from_up(hisaxif_t *hif, u_int prim, u_int nr, int dtyp, void *arg) {
layer2_t *l2;
printk(KERN_DEBUG __FUNCTION__ ": prim(%x)\n", prim);
if (!hif || !hif->fdata)
return(-EINVAL);
l2 = hif->fdata;
@ -1873,6 +1875,9 @@ l2from_up(hisaxif_t *hif, u_int prim, u_int nr, int dtyp, void *arg) {
case (MDL_STATUS | REQUEST):
l2up(l2, MDL_STATUS | CONFIRM, nr, 0, (void *)l2->tei);
break;
default:
l2m_debug(&l2->l2m, "l2 unknown pr %04x", prim);
return(-EINVAL);
}
return(0);
}
@ -1894,6 +1899,7 @@ tei_l2(layer2_t *l2, u_int prim, u_int nr, int dtyp, void *arg)
case (MDL_ERROR | RESPONSE):
FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, arg);
break;
#if 0
case (MDL_STATUS | REQUEST):
if (l2->inst.st && l2->inst.st->inst[1]) {
hisaxif_t *up = &l2->inst.st->inst[1]->up;
@ -1902,6 +1908,7 @@ tei_l2(layer2_t *l2, u_int prim, u_int nr, int dtyp, void *arg)
nr, dtyp, arg));
}
break;
#endif
}
return(0);
}
@ -1933,31 +1940,28 @@ release_l2(layer2_t *l2)
if (l2->ph_skb)
dev_kfree_skb(l2->ph_skb);
ReleaseWin(l2);
release_tei(l2->tm);
if (test_bit(FLG_LAPD, &l2->flag))
release_tei(l2->tm);
memset(&hif, 0, sizeof(hisaxif_t));
hif.fdata = l2;
hif.func = l2from_up;
hif.protocol = inst->up.protocol;
hif.layer = inst->up.layer;
hif.layermask = inst->up.layermask;
isdnl2.ctrl(inst->st, MGR_DELIF | REQUEST, &hif);
hif.fdata = l2;
hif.func = l2from_down;
hif.protocol = inst->down.protocol;
hif.layer = inst->down.layer;
hif.layermask = inst->down.layermask;
isdnl2.ctrl(inst->st, MGR_DELIF | REQUEST, &hif);
REMOVE_FROM_LISTBASE(l2, l2list);
REMOVE_FROM_LIST(inst);
if (inst->st)
if (inst->st->inst[inst->layer] == inst)
inst->st->inst[inst->layer] = inst->next;
isdnl2.ctrl(inst->st, MGR_DELLAYER | REQUEST, inst);
kfree(l2);
isdnl2.refcnt--;
}
static layer2_t *
create_l2(hisaxstack_t *st, hisaxif_t *hif) {
layer2_t *nl2;
int lay, err;
int err,lay;
if (!hif)
return(NULL);
@ -1966,16 +1970,21 @@ create_l2(hisaxstack_t *st, hisaxif_t *hif) {
printk(KERN_ERR "create_l2 no stack\n");
return(NULL);
}
lay = layermask2layer(hif->layermask);
if (lay < 0) {
int_errtxt("lm %x", hif->layermask);
return(NULL);
}
if (!(nl2 = kmalloc(sizeof(layer2_t), GFP_ATOMIC))) {
printk(KERN_ERR "kmalloc layer2 failed\n");
return(NULL);
}
memset(nl2, 0, sizeof(layer2_t));
nl2->debug = debug;
nl2->inst.protocol = hif->protocol;
switch(nl2->inst.protocol) {
nl2->inst.pid.protocol[lay] = hif->protocol;
switch(hif->protocol) {
case ISDN_PID_L2_LAPD:
sprintf(nl2->inst.id, "lapd %d", st->id);
sprintf(nl2->inst.id, "lapd %x", st->id);
test_and_set_bit(FLG_LAPD, &nl2->flag);
test_and_set_bit(FLG_MOD128, &nl2->flag);
test_and_set_bit(FLG_LAPD, &nl2->flag);
@ -1994,15 +2003,16 @@ create_l2(hisaxstack_t *st, hisaxif_t *hif) {
break;
case ISDN_PID_L2_B_X75SLP:
test_and_set_bit(FLG_LAPB, &nl2->flag);
sprintf(nl2->inst.id, "lapb %d", st->id);
sprintf(nl2->inst.id, "lapb %x", st->id);
nl2->window = 7;
nl2->maxlen = MAX_DATA_SIZE;
nl2->T200 = 1000;
nl2->N200 = 4;
nl2->T203 = 5000;
test_and_set_bit(FLG_ORIG, &nl2->flag);
break;
default:
printk(KERN_ERR "layer1 create failed prt %x\n",nl2->inst.protocol);
printk(KERN_ERR "layer1 create failed prt %x\n",hif->protocol);
kfree(nl2);
return(NULL);
}
@ -2024,25 +2034,15 @@ create_l2(hisaxstack_t *st, hisaxif_t *hif) {
FsmInitTimer(&nl2->l2m, &nl2->t200);
FsmInitTimer(&nl2->l2m, &nl2->t203);
nl2->inst.layer = hif->layer;
nl2->inst.layermask = hif->layermask;
nl2->inst.data = nl2;
APPEND_TO_LIST(nl2, l2list);
isdnl2.ctrl(st, MGR_ADDLAYER | INDICATION, &nl2->inst);
lay = nl2->inst.layer + 1;
if ((lay<0) || (lay>MAX_LAYER)) {
lay = 0;
nl2->inst.up.protocol = ISDN_PID_NONE;
} else
nl2->inst.up.protocol = st->protocols[lay];
nl2->inst.up.layer = lay;
nl2->inst.up.layermask = get_up_layer(nl2->inst.layermask);
nl2->inst.up.protocol = get_protocol(st, nl2->inst.up.layermask);
nl2->inst.up.stat = IF_DOWN;
lay = nl2->inst.layer - 1;
if ((lay<0) || (lay>MAX_LAYER)) {
lay = 0;
nl2->inst.down.protocol = ISDN_PID_NONE;
} else
nl2->inst.down.protocol = st->protocols[lay];
nl2->inst.down.layer = lay;
nl2->inst.down.layermask = get_down_layer(nl2->inst.layermask);
nl2->inst.down.protocol = get_protocol(st, nl2->inst.down.layermask);
nl2->inst.down.stat = IF_UP;
err = isdnl2.ctrl(st, MGR_ADDIF | REQUEST, &nl2->inst.down);
if (err) {
@ -2064,15 +2064,14 @@ add_if(layer2_t *l2, hisaxif_t *hif) {
int err;
hisaxinstance_t *inst = &l2->inst;
printk(KERN_DEBUG "layer2 add_if lay %d/%x prot %x\n", hif->layer,
printk(KERN_DEBUG "layer2 add_if lay %x/%x prot %x\n", hif->layermask,
hif->stat, hif->protocol);
hif->fdata = l2;
if (IF_TYPE(hif) == IF_UP) {
hif->func = l2from_up;
if (inst->up.stat == IF_NOACTIV) {
inst->up.stat = IF_DOWN;
inst->up.protocol =
inst->st->protocols[inst->up.layer];
inst->up.protocol = get_protocol(inst->st, inst->up.layermask);
err = isdnl2.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->up);
if (err)
inst->up.stat = IF_NOACTIV;
@ -2081,8 +2080,7 @@ add_if(layer2_t *l2, hisaxif_t *hif) {
hif->func = l2from_down;
if (inst->down.stat == IF_NOACTIV) {
inst->down.stat = IF_UP;
inst->down.protocol =
inst->st->protocols[inst->down.layer];
inst->down.protocol = get_protocol(inst->st, inst->down.layermask);
err = isdnl2.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->down);
if (err)
inst->down.stat = IF_NOACTIV;
@ -2097,7 +2095,7 @@ del_if(layer2_t *l2, hisaxif_t *hif) {
int err;
hisaxinstance_t *inst = &l2->inst;
printk(KERN_DEBUG "layer2 del_if lay %d/%x %p/%p\n", hif->layer,
printk(KERN_DEBUG "layer2 del_if lay %x/%x %p/%p\n", hif->layermask,
hif->stat, hif->func, hif->fdata);
if ((hif->func == inst->up.func) && (hif->fdata == inst->up.fdata)) {
inst->up.stat = IF_NOACTIV;
@ -2158,6 +2156,7 @@ l2_manager(void *data, u_int prim, void *arg) {
return(del_if(l2l, arg));
break;
case MGR_RELEASE | INDICATION:
case MGR_DELLAYER | REQUEST:
if (l2l) {
printk(KERN_DEBUG "release_l2 id %x\n", l2l->inst.st->id);
release_l2(l2l);
@ -2182,7 +2181,7 @@ int Isdnl2Init(void)
isdnl2.own_ctrl = l2_manager;
isdnl2.prev = NULL;
isdnl2.next = NULL;
isdnl2.layer = 2;
isdnl2.layermask = ISDN_LAYER(2);
l2fsm.state_count = L2_STATE_COUNT;
l2fsm.event_count = L2_EVENT_COUNT;
l2fsm.strEvent = strL2Event;

View File

@ -9,6 +9,9 @@
#include <linux/hisaxif.h>
#include <linux/skbuff.h>
#include "fsm.h"
#ifdef MEMDBG
#include "memdbg.h"
#endif
#define MAX_WINDOW 8

View File

@ -11,8 +11,8 @@
*
*/
#define __NO_VERSION__
#include "hisaxl3.h"
#include "helper.h"
#include "hisaxl3.h"
const char *l3_revision = "$Revision$";
@ -294,6 +294,7 @@ release_l3_process(l3_process_t *p)
if (!p)
return;
l3 = p->l3;
hisax_l3up(p, CC_RELEASE_CR | INDICATION, NULL);
REMOVE_FROM_LISTBASE(p, l3->proc);
StopAllL3Timer(p);
kfree(p);
@ -532,6 +533,8 @@ init_l3(layer3_t *l3)
void
release_l3(layer3_t *l3)
{
printk(KERN_DEBUG "release_l3(%p) proc(%p) global(%p) dummy(%p)\n",
l3, l3->proc, l3->global, l3->dummy);
while (l3->proc)
release_l3_process(l3->proc);
if (l3->global) {

View File

@ -7,6 +7,9 @@
#include <linux/hisaxif.h>
#include <linux/skbuff.h>
#include "fsm.h"
#ifdef MEMDBG
#include "memdbg.h"
#endif
#define SBIT(state) (1<<state)
#define ALL_STATES 0x03ffffff

View File

@ -2,8 +2,8 @@
*
*/
#include "hisax_capi.h"
#include "helper.h"
#include "hisax_capi.h"
#include "debug.h"
#include "dss1.h"
@ -123,7 +123,8 @@ static void ncci_connect_b3_req(struct FsmInst *fi, int event, void *arg)
FsmEvent(fi, EV_NCCI_CONNECT_B3_CONF, cmsg);
ncciRecvCmsg(ncci, cmsg);
printk(KERN_DEBUG "ncci_connect_b3_req NCCI %x cmsg->Info(%x)\n",
ncci->adrNCCI, cmsg->Info);
if (cmsg->Info < 0x1000)
ncciL4L3(ncci, DL_ESTABLISH | REQUEST, 0, 0);
}
@ -258,8 +259,7 @@ static void ncci_select_b_protocol(struct FsmInst *fi, int event, void *arg)
{
Ncci_t *ncci = fi->userdata;
// if (ncci->l4.st)
// ncciReleaseSt(ncci);
ncciReleaseSt(ncci);
ncciInitSt(ncci);
}
@ -338,13 +338,30 @@ void ncciInitSt(Ncci_t *ncci)
Cplci_t *cplci = ncci->cplci;
memset(&pid, 0, sizeof(hisax_pid_t));
pid.B1 = cplci->Bprotocol.B1protocol | ISDN_PID_LAYER1 | ISDN_PID_BCHANNEL_BIT;
pid.B2 = cplci->Bprotocol.B2protocol | ISDN_PID_LAYER2 | ISDN_PID_BCHANNEL_BIT;
pid.B3 = cplci->Bprotocol.B3protocol | ISDN_PID_LAYER3 | ISDN_PID_BCHANNEL_BIT;
if (cplci->Bprotocol.B1protocol > 23) {
int_errtxt("wrong B1 prot %x", cplci->Bprotocol.B1protocol);
return;
}
pid.protocol[1] = (1 << cplci->Bprotocol.B1protocol) |
ISDN_PID_LAYER(1) | ISDN_PID_BCHANNEL_BIT;
if (cplci->Bprotocol.B2protocol > 23) {
int_errtxt("wrong B2 prot %x", cplci->Bprotocol.B2protocol);
return;
}
pid.protocol[2] = (1 << cplci->Bprotocol.B2protocol) |
ISDN_PID_LAYER(2) | ISDN_PID_BCHANNEL_BIT;
if (cplci->Bprotocol.B3protocol > 23) {
int_errtxt("wrong B3 prot %x", cplci->Bprotocol.B3protocol);
return;
}
pid.protocol[3] = (1 << cplci->Bprotocol.B3protocol) |
ISDN_PID_LAYER(3) | ISDN_PID_BCHANNEL_BIT;
printk(KERN_DEBUG "ncciInitSt B1(%x) B2(%x) B3(%x) ch(%x)\n",
pid.B1, pid.B2, pid.B3, cplci->bchannel);
pid.protocol[1], pid.protocol[2], pid.protocol[3],
cplci->bchannel);
printk(KERN_DEBUG "ncciInitSt ch(%d) cplci->contr->binst(%p)\n",
cplci->bchannel & 3, cplci->contr->binst);
pid.protocol[4] = ISDN_PID_L4_B_CAPI20;
if ((cplci->bchannel & 0xf4) == 0x80) {
ncci->binst = contrSelChannel(cplci->contr, cplci->bchannel & 3);
} else {
@ -358,9 +375,14 @@ void ncciInitSt(Ncci_t *ncci)
#if 0
sp.headroom = 22; // reserve space for DATA_B3 IND message in skb's
#endif
memset(& ncci->binst->inst.pid, 0, sizeof(hisax_pid_t));
ncci->binst->inst.data = ncci;
ncci->binst->inst.layer = 4;
ncci->binst->inst.protocol = ISDN_PID_CAPI20;
ncci->binst->inst.layermask = ISDN_LAYER(4);
ncci->binst->inst.pid.protocol[4] = ISDN_PID_L4_B_CAPI20;
if (pid.protocol[3] == ISDN_PID_L3_B_TRANS) {
ncci->binst->inst.pid.protocol[3] = ISDN_PID_L3_B_TRANS;
ncci->binst->inst.layermask |= ISDN_LAYER(3);
}
retval = ncci->binst->inst.obj->ctrl(ncci->binst->inst.st,
MGR_ADDLAYER | INDICATION, &ncci->binst->inst);
if (retval) {
@ -375,7 +397,7 @@ void ncciInitSt(Ncci_t *ncci)
}
// if (sp.b2_mode != B2_MODE_TRANS || !test_bit(PLCI_FLAG_OUTGOING, &cplci->plci->flags)) {
// listen for e.g. SABME
ncciL4L3(ncci, PH_ACTIVATE | REQUEST, 0, 0);
// ncciL4L3(ncci, PH_ACTIVATE | REQUEST, 0, 0);
// }
}
@ -385,7 +407,8 @@ void ncciReleaseSt(Ncci_t *ncci)
ncciL4L3(ncci, PH_DEACTIVATE | REQUEST, 0, 0);
retval = ncci->binst->inst.obj->ctrl(ncci->binst->inst.st,
MGR_CLEARSTACK, NULL);
MGR_CLEARSTACK | REQUEST, NULL);
if (retval) {
int_error();
return;
@ -417,6 +440,7 @@ __u16 ncciSelectBprotocol(Ncci_t *ncci)
void ncciDestr(Ncci_t *ncci)
{
printk(KERN_DEBUG "ncciDestr NCCI %x\n", ncci->adrNCCI);
if (ncci->binst)
ncciReleaseSt(ncci);
if (ncci->appl)
@ -647,7 +671,7 @@ static int ncci_l3l4(hisaxif_t *hif, u_int prim, u_int nr, int dtyp, void *arg)
FsmEvent(&ncci->ncci_m, EV_NCCI_DL_RELEASE_CONF, arg);
break;
default:
printk("ncci_l3l4 prim(%x) dtyp(%x) arg(%p)\n",
printk(KERN_DEBUG __FUNCTION__ ": unknown prim(%x) dtyp(%x) arg(%p)\n",
prim, dtyp, arg);
int_error();
}
@ -661,6 +685,8 @@ void ncciSetInterface(hisaxif_t *hif) {
static int ncciL4L3(Ncci_t *ncci, u_int prim, int dtyp, void *arg)
{
printk(KERN_DEBUG __FUNCTION__ ": NCCI %x prim(%x)\n",
ncci->adrNCCI, prim);
if (!ncci->binst || !ncci->binst->inst.down.func) {
int_error();
return -EINVAL;

View File

@ -96,8 +96,6 @@ const char *Sedlbauer_Types[] =
#define SEDL_RESET 0x3 /* same as DOS driver */
#define SPIN_DEBUG 1
/* data struct */
typedef struct _sedl_fax {
@ -399,7 +397,6 @@ static sedl_fax *cardlist;
static int sedl_cnt;
static hisaxobject_t speedfax;
static int debug;
static u_int act_protocol;
static u_int protocol[MAX_CARDS];
static u_int io[MAX_CARDS];
static u_int irq[MAX_CARDS];
@ -592,17 +589,19 @@ add_if(hisaxinstance_t *inst, int channel, hisaxif_t *hif) {
case ISDN_PID_L1_B_TRANS_TTR:
case ISDN_PID_L1_B_TRANS_TTS:
case ISDN_PID_L1_B_64HDLC:
case ISDN_PID_L2_B_TRANS:
case ISDN_PID_L3_B_TRANS:
printk(KERN_DEBUG "speedfax_add_if ch%d p:%x\n", channel, hif->protocol);
if ((channel<0) || (channel>1))
return(-EINVAL);
hif->fdata = &card->bch[channel];
hif->func = isar_down;
inst->protocol = hif->protocol;
if (inst->up.stat == IF_NOACTIV) {
printk(KERN_DEBUG "speedfax_add_if set upif\n");
inst->up.stat = IF_DOWN;
inst->up.layer = hif->inst->layer;
inst->up.protocol = hif->inst->protocol;
inst->up.layermask = hif->inst->layermask;
inst->up.protocol = get_protocol(inst->st,
inst->up.layermask);;
err = speedfax.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->up);
if (err) {
printk(KERN_WARNING "speedfax_add_if up no if\n");
@ -617,8 +616,8 @@ add_if(hisaxinstance_t *inst, int channel, hisaxif_t *hif) {
hif->func = ISAC_l1hw;
if (inst->up.stat == IF_NOACTIV) {
inst->up.stat = IF_DOWN;
inst->up.protocol =
inst->st->protocols[inst->up.layer];
inst->up.protocol = get_protocol(inst->st,
inst->up.layermask);
err = speedfax.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->up);
if (err)
inst->up.stat = IF_NOACTIV;
@ -634,10 +633,9 @@ add_if(hisaxinstance_t *inst, int channel, hisaxif_t *hif) {
static int
del_if(hisaxinstance_t *inst, int channel, hisaxif_t *hif) {
int err;
sedl_fax *card = inst->data;
printk(KERN_DEBUG "speedfax del_if lay %d/%d %p/%p\n", hif->layer,
printk(KERN_DEBUG "speedfax del_if lay %x/%x %p/%p\n", hif->layermask,
hif->stat, hif->func, hif->fdata);
if ((hif->func == inst->up.func) && (hif->fdata == inst->up.fdata)) {
if (channel==2)
@ -671,34 +669,48 @@ release_card(sedl_fax *card) {
REMOVE_FROM_LISTBASE(card, cardlist);
unlock_dev(card);
kfree(card);
card = NULL;
sedl_cnt--;
speedfax.refcnt--;
}
static int
set_stack(hisaxstack_t *st, hisaxinstance_t *inst, int chan, hisax_pid_t *pid) {
int err,layer = 0;
int err, layer = 0;
#if 0
if (st->inst[0] || st->inst[1] || st->inst[2]) {
return(-EBUSY);
}
if (!HasProtocol(inst, pid->B1)) {
return(-EPROTONOSUPPORT);
} else
layer = 1;
if (HasProtocol(inst, pid->B2))
layer = 2;
if (HasProtocol(inst, pid->B3))
layer = 3;
inst->layer = layer;
inst->protocol = pid->B1;
#endif
memset(&inst->pid, 0, sizeof(hisax_pid_t));
if (chan == 2) { /* D-channel */
if (!HasProtocol(inst, pid->protocol[0])) {
return(-EPROTONOSUPPORT);
} else
layer = ISDN_LAYER(0);
inst->pid.protocol[0] = pid->protocol[0];
} else {
if (!HasProtocol(inst, pid->protocol[1])) {
return(-EPROTONOSUPPORT);
} else
layer = ISDN_LAYER(1);
inst->pid.protocol[1] = pid->protocol[1];
if (HasProtocol(inst, pid->protocol[2])) {
layer |= ISDN_LAYER(2);
inst->pid.protocol[2] = pid->protocol[2];
if (HasProtocol(inst, pid->protocol[3])) {
layer |= ISDN_LAYER(3);
inst->pid.protocol[3] = pid->protocol[3];
}
}
}
inst->layermask = layer;
if ((err = speedfax.ctrl(st, MGR_ADDLAYER | REQUEST, inst))) {
printk(KERN_WARNING "set_stack MGR_ADDLAYER err(%d)\n", err);
return(err);
}
inst->up.layer = layer + 1;
inst->up.protocol = st->protocols[layer+1];
inst->up.layermask = get_up_layer(layer);
inst->up.protocol = get_protocol(st, inst->up.layermask);
inst->up.inst = inst;
inst->up.stat = IF_DOWN;
if ((err = speedfax.ctrl(st, MGR_ADDIF | REQUEST, &inst->up))) {
@ -712,7 +724,7 @@ static int
speedfax_manager(void *data, u_int prim, void *arg) {
sedl_fax *card = cardlist;
hisaxinstance_t *inst=NULL;
int i,channel = -1;
int channel = -1;
hisaxstack_t *st = data;
if (!data) {
@ -749,20 +761,6 @@ speedfax_manager(void *data, u_int prim, void *arg) {
printk(KERN_WARNING "speedfax_manager no card found\n");
return(-ENODEV);
}
if (channel == 2) {
card->dch.inst.st->protocols[0] = ISDN_PID_L0_TE_S0;
card->dch.inst.st->protocols[1] = ISDN_PID_L1_TE_S0;
card->dch.inst.st->protocols[2] = ISDN_PID_L2_LAPD;
if (act_protocol == 2) {
card->dch.inst.st->protocols[3] = ISDN_PID_L3_DSS1USER;
card->dch.inst.st->protocols[4] = ISDN_PID_CAPI20;
} else {
card->dch.inst.st->protocols[3] = ISDN_PID_NONE;
card->dch.inst.st->protocols[4] = ISDN_PID_NONE;
}
} else {
break;
}
break;
case MGR_DELLAYER | REQUEST:
if (!card) {
@ -832,10 +830,11 @@ Speedfax_init(void)
{
int err,i;
sedl_fax *card;
hisax_pid_t pid;
speedfax.name = SpeedfaxName;
speedfax.own_ctrl = speedfax_manager;
speedfax.layer = 0;
speedfax.layermask = ISDN_LAYER(0);
speedfax.protocols = SpeedfaxProtocols;
speedfax.protcnt = SPEEDFAX_PCNT;
speedfax.prev = NULL;
@ -859,17 +858,27 @@ Speedfax_init(void)
card->dch.inst.lock = lock_dev;
card->dch.inst.unlock = unlock_dev;
card->dch.inst.data = card;
card->dch.inst.layer = 0;
card->dch.inst.protocol = ISDN_PID_L0_TE_S0;
card->dch.inst.up.inst = &card->dch.inst;
act_protocol = protocol[sedl_cnt];
card->dch.inst.down.func = dummy_down;
card->dch.inst.down.fdata = card;
memset(&pid, 0, sizeof(hisax_pid_t));
pid.protocol[0] = ISDN_PID_L0_TE_S0;
pid.protocol[1] = ISDN_PID_L1_TE_S0;
pid.protocol[2] = ISDN_PID_L2_LAPD;
if (protocol[sedl_cnt] == 2) {
pid.protocol[3] = ISDN_PID_L3_DSS1USER;
pid.protocol[4] = ISDN_PID_L4_CAPI20;
} else {
pid.protocol[3] = ISDN_PID_NONE;
pid.protocol[4] = ISDN_PID_NONE;
}
sprintf(card->dch.inst.id, "SFax%d", sedl_cnt+1);
init_dchannel(&card->dch);
for (i=0; i<2; i++) {
card->bch[i].inst.obj = &speedfax;
card->bch[i].inst.data = card;
card->bch[i].inst.layer = 0;
card->bch[i].inst.up.layer = 1;
card->bch[i].inst.layermask = 0;
card->bch[i].inst.up.layermask = ISDN_LAYER(1);
card->bch[i].inst.up.inst = &card->bch[i].inst;
card->bch[i].inst.lock = lock_dev;
card->bch[i].inst.unlock = unlock_dev;
@ -907,24 +916,9 @@ Speedfax_init(void)
err = 0;
return(err);
}
if ((err = speedfax.ctrl(card->dch.inst.st, MGR_ADDLAYER | REQUEST, &card->dch.inst))) {
printk(KERN_ERR "MGR_ADDLAYER REQUEST dch err(%d)\n", err);
release_card(card);
if (!sedl_cnt)
HiSax_unregister(&speedfax);
else
err = 0;
return(err);
}
card->dch.inst.up.layer = 1;
card->dch.inst.up.stat = IF_DOWN;
card->dch.inst.up.protocol = card->dch.inst.st->protocols[1];
card->dch.inst.down.func = dummy_down;
card->dch.inst.down.fdata = card;
if ((err = speedfax.ctrl(card->dch.inst.st, MGR_ADDIF | REQUEST,
&card->dch.inst.up))) {
printk(KERN_ERR "MGR_ADDIF REQUEST dch err(%d)\n", err);
release_card(card);
if ((err = speedfax.ctrl(card->dch.inst.st, MGR_SETSTACK | REQUEST, &pid))) {
printk(KERN_ERR "MGR_SETSTACK REQUEST dch err(%d)\n", err);
speedfax.ctrl(card->dch.inst.st, MGR_DELSTACK | REQUEST, NULL);
if (!sedl_cnt)
HiSax_unregister(&speedfax);
else
@ -935,7 +929,7 @@ Speedfax_init(void)
if ((err = speedfax.ctrl(card->dch.inst.st, MGR_ADDSTACK | REQUEST,
&card->bch[i].inst))) {
printk(KERN_ERR "MGR_ADDSTACK bchan error %d\n", err);
release_card(card);
speedfax.ctrl(card->dch.inst.st, MGR_DELSTACK | REQUEST, NULL);
if (!sedl_cnt)
HiSax_unregister(&speedfax);
else
@ -944,7 +938,7 @@ Speedfax_init(void)
}
}
if ((err = init_card(card))) {
release_card(card);
speedfax.ctrl(card->dch.inst.st, MGR_DELSTACK | REQUEST, NULL);
if (!sedl_cnt)
HiSax_unregister(&speedfax);
else

View File

@ -25,25 +25,36 @@ get_stack_cnt(void) {
void
get_stack_profile(iframe_t *frm) {
hisaxstack_t *cst, *st = hisax_stacklist;
int i,cnt = 0;
int *dp,*ccnt;
hisaxlayer_t *layer;
int cnt = 0;
int *dp,*ccnt,*lcnt;
while(st) {
cnt++;
if (cnt == frm->addr) {
dp = frm->data.p;
*dp++ = st->id;
for (i=0; i<=MAX_LAYER; i++) {
*dp++ = st->protocols[i];
lcnt = dp++;
layer = st->lstack;
*lcnt = 0;
while (layer && layer->inst) {
(*lcnt)++;
*dp++ = layer->inst->pid.protocol[0];
layer = layer->next;
}
ccnt=dp++;
ccnt = dp++;
*ccnt=0;
cst = st->child;
while(cst) {
(*ccnt)++;
*dp++ = cst->id;
for (i=0; i<=MAX_LAYER; i++) {
*dp++ = cst->protocols[i];
lcnt = dp++;
*lcnt = 0;
layer = cst->lstack;
while (layer && layer->inst) {
(*lcnt)++;
*dp++ = layer->inst->pid.protocol[0];
layer = layer->next;
}
cst = cst->next;
}
@ -113,6 +124,130 @@ get_stack4id(int id)
return(NULL);
}
hisaxlayer_t *
getlayer4lay(hisaxstack_t *st, int layermask)
{
hisaxlayer_t *layer;
hisaxinstance_t *inst;
if (!st) {
int_error();
return(NULL);
}
layer = st->lstack;
while(layer) {
inst = layer->inst;
while(inst) {
if (inst->layermask & layermask)
goto out;
inst = inst->next;
}
layer = layer->next;
}
out:
return(layer);
}
hisaxinstance_t *
get_instance(hisaxstack_t *st, int layer_nr, int protocol)
{
hisaxlayer_t *layer;
hisaxinstance_t *inst=NULL;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "get_instance st(%p) lnr(%d) prot(%x)\n",
st, layer_nr, protocol);
if (!st) {
int_error();
return(NULL);
}
if ((layer_nr<0) || (layer_nr>MAX_LAYER_NR)) {
int_errtxt("lnr %d", layer_nr);
return(NULL);
}
layer = st->lstack;
while(layer) {
inst = layer->inst;
while(inst) {
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "get_instance inst(%p) lm %x/%x prot %x/%x\n",
inst, inst->layermask, ISDN_LAYER(layer_nr),
inst->pid.protocol[layer_nr], protocol);
if ((inst->layermask & ISDN_LAYER(layer_nr)) &&
(inst->pid.protocol[layer_nr] == protocol))
goto out;
inst = inst->next;
}
layer = layer->next;
}
out:
return(inst);
}
int
get_layermask(hisaxlayer_t *layer)
{
int mask = 0;
hisaxinstance_t *inst;
inst = layer->inst;
while(inst) {
mask |= inst->layermask;
inst = inst->next;
}
return(mask);
}
int
insertlayer(hisaxstack_t *st, hisaxlayer_t *layer, int layermask)
{
hisaxlayer_t *item;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG __FUNCTION__"(%p, %p, %x)\n",
st, layer, layermask);
if (!st || !layer) {
int_error();
return(-EINVAL);
}
item = st->lstack;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "lstack(%p)",
st->lstack);
if (!item) {
st->lstack = layer;
if (core_debug & DEBUG_CORE_FUNC)
printk("\n");
} else {
while(item) {
if (layermask < get_layermask(item)) {
if (core_debug & DEBUG_CORE_FUNC)
printk(" item(%p) lm(%x) prev(%p)\n",
item, get_layermask(item),
item->prev);
layer->next = item;
layer->prev = item->prev;
if (layer->prev)
layer->prev->next = layer;
item->prev = layer;
if (st->lstack == item)
st->lstack = layer;
return(0);
} else {
if (!item->next)
break;
}
item = item->next;
}
if (core_debug & DEBUG_CORE_FUNC)
printk(" item(%p) lm(%x)\n",
item, get_layermask(item));
item->next = layer;
layer->prev = item;
}
return(0);
}
hisaxstack_t *
new_stack(hisaxinstance_t *inst, hisaxstack_t *master) {
hisaxstack_t *newst;
@ -137,40 +272,50 @@ new_stack(hisaxinstance_t *inst, hisaxstack_t *master) {
return(newst);
}
static int
release_childstack(hisaxstack_t *st, hisaxstack_t *cst) {
int l;
hisaxinstance_t *inst, *tmp;
for(l=0;l<=MAX_LAYER;l++) {
inst = cst->inst[l];
static int
release_layers(hisaxstack_t *st, u_int prim) {
hisaxinstance_t *inst, *tmp;
hisaxlayer_t *layer;
int cnt = 0;
while((layer = st->lstack)) {
inst = layer->inst;
while (inst) {
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG __FUNCTION__ ": st(%p) inst(%p) lm(%x)\n",
st, inst, inst->layermask);
tmp = inst->next;
inst->obj->own_ctrl(cst, MGR_RELEASE | INDICATION,
inst);
inst->obj->own_ctrl(st, prim, inst);
inst = tmp;
}
REMOVE_FROM_LISTBASE(layer, st->lstack);
kfree(layer);
if (cnt++ > 1000) {
int_errtxt("release_layers st(%p)", st);
return(-EINVAL);
}
}
REMOVE_FROM_LISTBASE(cst, st->child);
kfree(cst);
return(0);
}
static int
int
release_stack(hisaxstack_t *st) {
int l;
hisaxinstance_t *inst, *tmp;
int err;
hisaxstack_t *cst;
while (st->child)
release_childstack(st, st->child);
for(l=0;l<=MAX_LAYER;l++) {
inst = st->inst[l];
while (inst) {
tmp = inst->next;
inst->obj->own_ctrl(st, MGR_RELEASE | INDICATION,
inst);
inst = tmp;
while (st->child) {
cst = st->child;
if ((err = release_layers(cst, MGR_RELEASE | INDICATION))) {
printk(KERN_WARNING "release_stack child err(%d)\n", err);
return(err);
}
REMOVE_FROM_LISTBASE(cst, st->child);
kfree(cst);
}
if ((err = release_layers(st, MGR_RELEASE | INDICATION))) {
printk(KERN_WARNING "release_stack err(%d)\n", err);
return(err);
}
REMOVE_FROM_LISTBASE(st, hisax_stacklist);
kfree(st);
@ -180,21 +325,22 @@ release_stack(hisaxstack_t *st) {
void
release_stacks(hisaxobject_t *obj) {
hisaxstack_t *st, *tmp;
hisaxlayer_t *layer;
hisaxinstance_t *inst;
int l, rel;
int rel;
if (!obj->refcnt)
return;
st = hisax_stacklist;
while (st) {
rel = 0;
for (l=0;l<=MAX_LAYER;l++) {
inst = st->inst[l];
layer = st->lstack;
while(layer) {
inst = layer->inst;
while (inst) {
if (inst->obj == obj)
rel++;
inst = inst->next;
}
layer = layer->next;
}
if (rel) {
tmp = st->next;
@ -208,6 +354,50 @@ release_stacks(hisaxobject_t *obj) {
obj->name, obj->refcnt);
}
int
register_layer(hisaxstack_t *st, hisaxinstance_t *inst) {
int lay;
hisaxlayer_t *layer;
if (!st || !inst)
return(-EINVAL);
lay = inst->layermask;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "register_layer st(%p) inst(%p) lmask(%x)\n",
st, inst, lay);
if (!(layer = getlayer4lay(st, lay))) {
if (!(layer = kmalloc(sizeof(hisaxlayer_t), GFP_ATOMIC))) {
int_errtxt("no mem for layer %d", lay);
return(-ENOMEM);
}
memset(layer, 0, sizeof(hisaxlayer_t));
insertlayer(st, layer, lay);
}
APPEND_TO_LIST(inst, layer->inst);
inst->st = st;
inst->obj->refcnt++;
return(0);
}
int
unregister_instance(hisaxinstance_t *inst) {
hisaxstack_t *st;
hisaxlayer_t *layer;
if (!inst || !inst->st)
return(-EINVAL);
st = inst->st;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "unregister_instance st(%p) inst(%p) lay(%x)\n",
st, inst, inst->layermask);
if ((layer = getlayer4lay(st, inst->layermask))) {
REMOVE_FROM_LISTBASE(inst, layer->inst);
inst->obj->refcnt--;
} else
return(-ENODEV);
return(0);
}
int
set_stack(hisaxstack_t *st, hisax_pid_t *pid) {
@ -220,23 +410,14 @@ set_stack(hisaxstack_t *st, hisax_pid_t *pid) {
int_error();
return(-EINVAL);
}
st->protocols[1] = st->pid.B1;
st->protocols[2] = st->pid.B2;
st->protocols[3] = st->pid.B3;
return(st->mgr->obj->own_ctrl(st, MGR_SETSTACK | REQUEST, &st->pid));
}
int
clear_stack(hisaxstack_t *st) {
int i;
if (!st)
return(-EINVAL);
for (i=0; i<=MAX_LAYER; i++) {
if (st->inst[i])
st->inst[i]->obj->own_ctrl(st, MGR_DELLAYER | REQUEST,
st->inst[i]);
st->protocols[i] = ISDN_PID_NONE;
}
return(0);
memset(&st->pid, 0, sizeof(hisax_pid_t));
return(release_layers(st, MGR_DELLAYER | REQUEST));
}

View File

@ -39,7 +39,7 @@ static rwlock_t hisax_device_lock = RW_LOCK_UNLOCKED;
static hisaxobject_t udev_obj;
static char MName[] = "UserDevice";
static int stbuf[32*(MAX_LAYER+2)];
static int stbuf[1000];
static int device_debug = 0;
@ -91,18 +91,16 @@ static devicelayer_t
static int
create_layer(hisaxdevice_t *dev, hisaxstack_t *st, int *ip) {
int ret;
u_char *p;
devicelayer_t *nl;
hisaxlayer_t *layer;
int ret;
u_char *p;
devicelayer_t *nl;
if ((*ip < 0) || (*ip > MAX_LAYER))
return(-EINVAL);
if (st->inst[*ip]) {
if ((layer = getlayer4lay(st, *ip))) {
printk(KERN_WARNING
"HiSax create_layer st(%d) lay(%d) inst not empty(%p)\n",
st->id, *ip, st->inst[*ip]);
return(-EBUSY);
}
st->id, *ip, layer);
}
if (!(nl = kmalloc(sizeof(devicelayer_t), GFP_ATOMIC))) {
printk(KERN_ERR "kmalloc devicelayer failed\n");
return(-ENOMEM);
@ -113,24 +111,16 @@ create_layer(hisaxdevice_t *dev, hisaxstack_t *st, int *ip) {
"HiSax create_layer lay(%d) nl(%p) nl inst(%p)\n",
*ip, nl, &nl->inst);
nl->dev = dev;
nl->inst.layer = *ip++;
nl->inst.protocol = *ip++;
nl->inst.layermask = *ip++;
nl->inst.pid.protocol[0] = *ip++;
p = (u_char *)ip;
strcpy(nl->inst.id, p);
p += HISAX_MAX_IDLEN;
ip = (int *)p;
nl->inst.down.protocol = *ip++;
if ((*ip < 0) || (*ip > MAX_LAYER)) {
kfree(nl);
return(-EINVAL);
}
nl->inst.down.layer = *ip++;
nl->inst.down.layermask = *ip++;
nl->inst.up.protocol = *ip++;
if ((*ip < 0) || (*ip > MAX_LAYER)) {
kfree(nl);
return(-EINVAL);
}
nl->inst.up.layer = *ip++;
nl->inst.up.layermask = *ip++;
nl->inst.obj = &udev_obj;
nl->inst.data = nl;
APPEND_TO_LIST(nl, dev->layer);
@ -145,7 +135,8 @@ create_layer(hisaxdevice_t *dev, hisaxstack_t *st, int *ip) {
if (ret) {
nl->inst.up.stat = IF_NOACTIV;
}
nl->iaddr = st->id | IADDR_BIT | (0x000F0000 & (nl->inst.layer << 16));
nl->iaddr = st->id | IADDR_BIT |
(IF_LAYERMASK & (nl->inst.layermask << 16));
ret = nl->iaddr;
return(ret);
}
@ -157,8 +148,8 @@ del_layer(devicelayer_t *dl) {
hisaxdevice_t *dev = dl->dev;
if (device_debug & DEBUG_MGR_FUNC) {
printk(KERN_DEBUG "del_layer: dl(%p) inst(%p) lay(%d) dev(%p) nexti(%p)\n",
dl, inst, inst->layer, dev, inst->next);
printk(KERN_DEBUG "del_layer: dl(%p) inst(%p) lay(%x) dev(%p) nexti(%p)\n",
dl, inst, inst->layermask, dev, inst->next);
printk(KERN_DEBUG "del_layer iaddr %x inst %s\n",
dl->iaddr, inst->id);
}
@ -166,28 +157,17 @@ del_layer(devicelayer_t *dl) {
hif.fdata = dl;
hif.func = from_up_down;
hif.protocol = inst->up.protocol;
hif.layer = inst->up.layer;
hif.layermask = inst->up.layermask;
udev_obj.ctrl(inst->st, MGR_DELIF | REQUEST, &hif);
hif.fdata = dl;
hif.func = from_up_down;
hif.protocol = inst->down.protocol;
hif.layer = inst->down.layer;
hif.layermask = inst->down.layermask;
udev_obj.ctrl(inst->st, MGR_DELIF | REQUEST, &hif);
dl->iaddr = 0;
REMOVE_FROM_LISTBASE(dl, dev->layer);
REMOVE_FROM_LIST(inst);
if (inst->st) {
if (device_debug & DEBUG_MGR_FUNC)
printk(KERN_DEBUG
"del_layer: st(%p) st->prot(l)%x st->inst(l) %p\n",
inst->st, inst->st->protocols[inst->layer],
inst->st->inst[inst->layer]);
inst->st->protocols[inst->layer] = ISDN_PID_NONE;
if (inst->st->inst[inst->layer] == inst)
inst->st->inst[inst->layer] = inst->next;
}
udev_obj.ctrl(inst->st, MGR_DELLAYER | REQUEST, inst);
kfree(dl);
udev_obj.refcnt--;
return(0);
}
@ -260,11 +240,12 @@ hisax_wdata(hisaxdevice_t *dev, void *dp, int len) {
iframe_t off;
hisaxstack_t *st;
devicelayer_t *dl;
hisaxlayer_t *layer;
int lay;
int err = 0;
int used = 0;
int head = 4*sizeof(u_int);
int *ip,i;
int *ip;
if (len < head) {
printk(KERN_WARNING "hisax: if_frame(%d) too short\n", len);
@ -299,22 +280,22 @@ hisax_wdata(hisaxdevice_t *dev, void *dp, int len) {
off.nr = iff->nr;
lay = iff->data.i;
off.len = 0;
if ((lay >= 0) && (lay <= MAX_LAYER)) {
if ((st = get_stack4id(iff->addr))) {
if (st->inst[lay]) {
off.data.p = stbuf;
ip = stbuf;
*ip++ = st->inst[lay]->layer;
*ip++ = st->inst[lay]->protocol;
if (st->inst[lay]->obj) {
*ip++ = st->inst[lay]->obj->protcnt;
for (i=0; i<st->inst[lay]->obj->protcnt; i++) {
*ip++ = st->inst[lay]->obj->protocols[i];
}
} else
*ip++ = 0;
off.len = (u_char *)ip - (u_char *)stbuf;
}
if ((st = get_stack4id(iff->addr))) {
if ((layer = getlayer4lay(st, lay))) {
off.data.p = stbuf;
ip = stbuf;
#if 0
*ip++ = st->inst[lay]->layer;
*ip++ = st->inst[lay]->protocol;
if (st->inst[lay]->obj) {
*ip++ = st->inst[lay]->obj->protcnt;
for (i=0; i<st->inst[lay]->obj->protcnt; i++) {
*ip++ = st->inst[lay]->obj->protocols[i];
}
} else
#endif
*ip++ = 0;
off.len = (u_char *)ip - (u_char *)stbuf;
}
}
hisax_rdata(dev, &off, 0);
@ -649,15 +630,15 @@ add_if(devicelayer_t *dl, hisaxif_t *hif) {
hisaxinstance_t *inst = &dl->inst;
if (device_debug & DEBUG_MGR_FUNC)
printk(KERN_DEBUG "userdev add_if lay %d/%x prot %x\n", hif->layer,
hif->stat, hif->protocol);
printk(KERN_DEBUG "userdev add_if lay %x/%x prot %x\n",
hif->layermask, hif->stat, hif->protocol);
hif->fdata = dl;
if (IF_TYPE(hif) == IF_UP) {
hif->func = from_up_down;
if (inst->up.stat == IF_NOACTIV) {
inst->up.stat = IF_DOWN;
inst->up.protocol =
inst->st->protocols[inst->up.layer];
inst->up.protocol = get_protocol(inst->st,
inst->up.layermask);
err = udev_obj.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->up);
if (err)
inst->up.stat = IF_NOACTIV;
@ -666,8 +647,8 @@ add_if(devicelayer_t *dl, hisaxif_t *hif) {
hif->func = from_up_down;
if (inst->down.stat == IF_NOACTIV) {
inst->down.stat = IF_UP;
inst->down.protocol =
inst->st->protocols[inst->down.layer];
inst->down.protocol = get_protocol(inst->st,
inst->down.layermask);
err = udev_obj.ctrl(inst->st, MGR_ADDIF | REQUEST, &inst->down);
if (err)
inst->down.stat = IF_NOACTIV;
@ -683,8 +664,8 @@ del_if(devicelayer_t *dl, hisaxif_t *hif) {
hisaxinstance_t *inst = &dl->inst;
if (device_debug & DEBUG_MGR_FUNC)
printk(KERN_DEBUG "dev del_if lay %d/%d %p/%p\n", hif->layer,
hif->stat, hif->func, hif->fdata);
printk(KERN_DEBUG "dev del_if lay %x/%x %p/%p\n",
hif->layermask, hif->stat, hif->func, hif->fdata);
if ((hif->func == inst->up.func) && (hif->fdata == inst->up.fdata)) {
inst->up.stat = IF_NOACTIV;
inst->up.protocol = ISDN_PID_NONE;
@ -761,7 +742,7 @@ int init_hisaxdev (int debug) {
udev_obj.own_ctrl = udev_manager;
udev_obj.prev = NULL;
udev_obj.next = NULL;
udev_obj.layer = -1;
udev_obj.layermask = -1;
device_debug = debug;
if (register_chrdev(HISAX_MAJOR, "hisax", &hisax_fops)) {
printk(KERN_WARNING "hisax: Could not register devices\n");

View File

@ -185,26 +185,27 @@
#define ISDN_PID_L1_NT_S0 0x01000101
#define ISDN_PID_L1_TE_U 0x01000002
#define ISDN_PID_L1_NT_U 0x01000102
#define ISDN_PID_L1_B_64HDLC 0x41000000
#define ISDN_PID_L1_B_64TRANS 0x41000001
#define ISDN_PID_L1_B_TRANS_TTS 0x41000101
#define ISDN_PID_L1_B_TRANS_TTR 0x41000201
#define ISDN_PID_L1_B_TRANS_TT 0x41000301
#define ISDN_PID_L1_B_V32 0x41000008
#define ISDN_PID_L1_B_FAX 0x41000004
#define ISDN_PID_L1_B_64HDLC 0x41000001
#define ISDN_PID_L1_B_64TRANS 0x41000002
#define ISDN_PID_L1_B_TRANS_TTS 0x41100002
#define ISDN_PID_L1_B_TRANS_TTR 0x41200002
#define ISDN_PID_L1_B_TRANS_TT 0x41300002
#define ISDN_PID_L1_B_V32 0x41000100
#define ISDN_PID_L1_B_FAX 0x41000010
#define ISDN_PID_L2_LAPD 0x02000001
#define ISDN_PID_L2_B_X75SLP 0x42000000
#define ISDN_PID_L2_B_TRANS 0x42000001
#define ISDN_PID_L3_B_TRANS 0x43000000
#define ISDN_PID_L2_B_X75SLP 0x42000001
#define ISDN_PID_L2_B_TRANS 0x42000002
#define ISDN_PID_L3_B_TRANS 0x43000001
#define ISDN_PID_L3_DSS1USER 0x03000001
#define ISDN_PID_CAPI20 0x04000001
#define ISDN_PID_L4_CAPI20 0x04000001
#define ISDN_PID_L4_B_CAPI20 0x44000001
#define ISDN_PID_BCHANNEL_BIT 0x40000000
#define ISDN_PID_LAYER1 0x01000000
#define ISDN_PID_LAYER2 0x02000000
#define ISDN_PID_LAYER3 0x03000000
#define ISDN_PID_LAYER(n) (n<<24)
#define MAX_LAYER_NR 7
#define ISDN_LAYER(n) (1<<n)
#define MAX_LAYER 4
#define HISAX_MAX_IDLEN 16
#define IADDR_BIT 0x10000000
@ -216,7 +217,7 @@
#define IF_TYPEMASK 0x07000000
#define IF_ADDRMASK 0x00FFFFFF
#define IF_IADDRMASK 0xF0FFFFFF
#define IF_LAYERMASK 0x000F0000
#define IF_LAYERMASK 0x00FF0000
#define IF_TYPE(i) ((i)->stat & IF_TYPEMASK)
#define DTYPE_SKB -1
@ -258,28 +259,16 @@ typedef struct _logdata {
typedef struct _moditem {
char *name;
int layer;
int layermask;
int protocol;
} moditem_t;
#define PROTO_PARA_PID 1
#define PROTO_PARA_BPROTOCOL 2
typedef struct _hisax_pid {
u_int B1;
u_int B2;
u_int B3;
void *B1p;
void *B2p;
void *B3p;
int protocol[MAX_LAYER_NR +1];
void *param[MAX_LAYER_NR +1];
void *global;
} hisax_pid_t;
typedef struct _bsetup {
int channel;
int flags;
u_int protocol[MAX_LAYER+1];
} bsetup_t;
typedef struct _l3msg_t {
int id;
@ -478,7 +467,7 @@ typedef struct _hisaxobject {
struct _hisaxobject *prev;
struct _hisaxobject *next;
char *name;
int layer;
int layermask;
int refcnt;
int protcnt;
int *protocols;
@ -490,7 +479,7 @@ typedef struct _hisaxobject {
typedef struct _hisaxif {
struct _hisaxif *prev;
struct _hisaxif *next;
int layer;
int layermask;
int protocol;
int stat;
struct _hisaxstack *st;
@ -502,8 +491,8 @@ typedef struct _hisaxif {
typedef struct _hisaxinstance {
struct _hisaxinstance *prev;
struct _hisaxinstance *next;
int layer;
int protocol;
int layermask;
hisax_pid_t pid;
char id[HISAX_MAX_IDLEN];
struct _hisaxstack *st;
hisaxobject_t *obj;
@ -514,21 +503,29 @@ typedef struct _hisaxinstance {
void (*unlock)(void *);
} hisaxinstance_t;
typedef struct _hisaxlayer {
struct _hisaxlayer *prev;
struct _hisaxlayer *next;
hisaxinstance_t *inst;
} hisaxlayer_t;
typedef struct _hisaxstack {
struct _hisaxstack *prev;
struct _hisaxstack *next;
u_int id;
hisax_pid_t pid;
int protocols[MAX_LAYER+1];
hisaxinstance_t *inst[MAX_LAYER+1];
hisaxlayer_t *lstack;
hisaxinstance_t *mgr;
struct _hisaxstack *child;
} hisaxstack_t;
/* common helper functions */
extern int bprotocol2pid(void *, hisax_pid_t *);
extern int get_protocol(hisaxstack_t *, int);
extern int HasProtocol(hisaxinstance_t *, int);
extern int DelIF(hisaxinstance_t *, hisaxif_t *, void *, void *);
/* global functions */
/* global exported functions */
extern int HiSax_register(hisaxobject_t *obj);
extern int HiSax_unregister(hisaxobject_t *obj);