working X75 orginating call
This commit is contained in:
parent
fb3bf581f4
commit
d34984bb05
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))) {
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
#include "../avmb1/capilli.h"
|
||||
#include "asn1.h"
|
||||
#include "fsm.h"
|
||||
#ifdef MEMDBG
|
||||
#include "memdbg.h"
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// common stuff
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue