add support for cloned stacks
messages queues can be temporary stopped now some cleanups
This commit is contained in:
parent
9aa4b41d68
commit
865dfe93b2
|
@ -577,9 +577,8 @@ ControllerConstr(Controller_t **contr_p, mISDNstack_t *st, mISDN_pid_t *pid, mIS
|
|||
ControllerDestr(contr);
|
||||
return -ENOMEM;
|
||||
}
|
||||
// FIXME ???
|
||||
contr->addr = st->id;
|
||||
sprintf(contr->inst.name, "CAPI %d", st->id);
|
||||
contr->addr = (st->id >> 8) & 0xff;
|
||||
sprintf(contr->inst.name, "CAPI %d", contr->addr);
|
||||
mISDN_init_instance(&contr->inst, ocapi, contr, ControllerL3L4);
|
||||
if (!mISDN_SetHandledPID(ocapi, &contr->inst.pid)) {
|
||||
int_error();
|
||||
|
@ -613,14 +612,14 @@ ControllerConstr(Controller_t **contr_p, mISDNstack_t *st, mISDN_pid_t *pid, mIS
|
|||
{
|
||||
char tmp[10];
|
||||
|
||||
sprintf(tmp, "mISDN%d", st->id);
|
||||
sprintf(tmp, "mISDN%d", (st->id >> 8) & 0xff);
|
||||
contr->ctrl = cdrv_if->attach_ctr(&mISDN_driver, tmp, contr);
|
||||
if (!contr->ctrl)
|
||||
retval = -ENODEV;
|
||||
}
|
||||
#else
|
||||
contr->ctrl->owner = THIS_MODULE;
|
||||
sprintf(contr->ctrl->name, "mISDN%d", st->id);
|
||||
sprintf(contr->ctrl->name, "mISDN%d", contr->addr);
|
||||
contr->ctrl->driver_name = "mISDN";
|
||||
contr->ctrl->driverdata = contr;
|
||||
contr->ctrl->register_appl = RegisterApplication;
|
||||
|
@ -633,6 +632,8 @@ ControllerConstr(Controller_t **contr_p, mISDNstack_t *st, mISDN_pid_t *pid, mIS
|
|||
retval = attach_capi_ctr(contr->ctrl);
|
||||
#endif
|
||||
if (!retval) {
|
||||
printk(KERN_DEBUG "contr->addr(%02x) cnr(%02x) st(%08x)\n",
|
||||
contr->addr, contr->ctrl->cnr, st->id);
|
||||
contr->addr = contr->ctrl->cnr;
|
||||
plciInit(contr);
|
||||
ocapi->ctrl(st, MGR_REGLAYER | INDICATION, &contr->inst);
|
||||
|
|
|
@ -578,6 +578,10 @@ static int central_manager(void *data, u_int prim, void *arg) {
|
|||
return(release_stack(st));
|
||||
case MGR_SELCHANNEL | REQUEST:
|
||||
return(sel_channel(st, arg));
|
||||
case MGR_STOPSTACK | REQUEST:
|
||||
return(mISDN_start_stop(st, 0));
|
||||
case MGR_STARTSTACK | REQUEST:
|
||||
return(mISDN_start_stop(st, 1));
|
||||
#ifdef FIXME
|
||||
case MGR_ADDIF | REQUEST:
|
||||
return(add_if(data, prim, arg));
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
|
||||
/* debugging */
|
||||
#define DEBUG_CORE_FUNC 0x0001
|
||||
#define DEBUG_DUMMY_FUNC 0x0002
|
||||
//#define DEBUG_DUMMY_FUNC 0x0002
|
||||
#define DEBUG_MSG_THREAD_ERR 0x0010
|
||||
#define DEBUG_MSG_THREAD_INFO 0x0020
|
||||
#define DEBUG_QUEUE_FUNC 0x0040
|
||||
#define DEBUG_DEV_OP 0x0100
|
||||
#define DEBUG_MGR_FUNC 0x0200
|
||||
#define DEBUG_DEV_TIMER 0x0400
|
||||
|
@ -42,6 +45,7 @@ extern void get_stack_info(struct sk_buff *);
|
|||
extern int get_stack_cnt(void);
|
||||
extern mISDNstack_t *get_stack4id(u_int);
|
||||
extern mISDNstack_t *new_stack(mISDNstack_t *, mISDNinstance_t *);
|
||||
extern int mISDN_start_stop(mISDNstack_t *, int);
|
||||
extern int release_stack(mISDNstack_t *);
|
||||
extern int do_for_all_layers(void *, u_int, void *);
|
||||
extern int change_stack_para(mISDNstack_t *, u_int, mISDN_stPara_t *);
|
||||
|
|
|
@ -5,9 +5,13 @@
|
|||
* This file is (c) under GNU PUBLIC LICENSE
|
||||
*
|
||||
*/
|
||||
#ifndef MISDN_DEBUG_H
|
||||
|
||||
#define MISDN_DEBUG_MANAGER 0x10000
|
||||
|
||||
extern void vmISDN_debug(int id, char *head, char *fmt, va_list args);
|
||||
extern void mISDN_debug(int id, char *head, char *fmt, ...);
|
||||
extern char * mISDN_getrev(const char *revision);
|
||||
extern void mISDN_debugprint(mISDNinstance_t *inst, char *fmt, ...);
|
||||
extern int mISDN_QuickHex(char *, u_char *, int);
|
||||
#endif
|
||||
|
|
|
@ -583,9 +583,10 @@ dtmf_manager(void *data, u_int prim, void *arg) {
|
|||
}
|
||||
switch(prim) {
|
||||
case MGR_CLRSTPARA | INDICATION:
|
||||
case MGR_CLONELAYER | REQUEST:
|
||||
break;
|
||||
#ifdef OBSOLATE
|
||||
case MGR_CLONELAYER | REQUEST:
|
||||
break;
|
||||
case MGR_CONNECT | REQUEST:
|
||||
return(mISDN_ConnectIF(inst, arg));
|
||||
case MGR_SETIF | REQUEST:
|
||||
|
|
|
@ -1929,7 +1929,7 @@ hfcpci_l2l1(mISDNinstance_t *inst, struct sk_buff *skb)
|
|||
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, ret, skb));
|
||||
} else if ((hh->prim == (PH_DEACTIVATE | REQUEST)) ||
|
||||
(hh->prim == (DL_RELEASE | REQUEST)) ||
|
||||
(hh->prim == (MGR_DISCONNECT | REQUEST))) {
|
||||
((hh->prim == (PH_CONTROL | REQUEST) && (hh->dinfo == HW_DEACTIVATE)))) {
|
||||
bch->inst.lock(hc, 0);
|
||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||
dev_kfree_skb(bch->next_skb);
|
||||
|
@ -1940,7 +1940,7 @@ hfcpci_l2l1(mISDNinstance_t *inst, struct sk_buff *skb)
|
|||
test_and_clear_bit(BC_FLG_ACTIV, &bch->Flag);
|
||||
bch->inst.unlock(hc);
|
||||
skb_trim(skb, 0);
|
||||
if (hh->prim != (MGR_DISCONNECT | REQUEST)) {
|
||||
if (hh->prim != (PH_CONTROL | REQUEST)) {
|
||||
#ifdef FIXME
|
||||
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
|
||||
if (bch->dev)
|
||||
|
@ -2360,8 +2360,8 @@ HFC_manager(void *data, u_int prim, void *arg) {
|
|||
dev_kfree_skb(skb);
|
||||
}
|
||||
} else {
|
||||
if ((skb = create_link_skb(MGR_DISCONNECT | REQUEST,
|
||||
0, 0, NULL, 0))) {
|
||||
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
||||
HW_DEACTIVATE, 0, NULL, 0))) {
|
||||
if (hfcpci_l2l1(inst, skb))
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
@ -2574,6 +2574,7 @@ static int __init HFC_init(void)
|
|||
}
|
||||
dst = card->dch.inst.st;
|
||||
}
|
||||
HFC_obj.ctrl(dst, MGR_STOPSTACK | REQUEST, NULL);
|
||||
for (i = 0; i < 2; i++) {
|
||||
if ((err = HFC_obj.ctrl(dst,
|
||||
MGR_NEWSTACK | REQUEST, &card->bch[i].inst))) {
|
||||
|
@ -2609,6 +2610,7 @@ static int __init HFC_init(void)
|
|||
err = 0;
|
||||
return(err);
|
||||
}
|
||||
HFC_obj.ctrl(dst, MGR_STARTSTACK | REQUEST, NULL);
|
||||
HFC_obj.ctrl(dst, MGR_CTRLREADY | INDICATION, NULL);
|
||||
}
|
||||
printk(KERN_INFO "HFC %d cards installed\n", HFC_cnt);
|
||||
|
|
|
@ -1645,7 +1645,7 @@ isar_down(mISDNinstance_t *inst, struct sk_buff *skb)
|
|||
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, ret, skb));
|
||||
} else if ((hh->prim == (PH_DEACTIVATE | REQUEST)) ||
|
||||
(hh->prim == (DL_RELEASE | REQUEST)) ||
|
||||
(hh->prim == (MGR_DISCONNECT | REQUEST))) {
|
||||
((hh->prim == (PH_CONTROL | REQUEST) && (hh->dinfo == HW_DEACTIVATE)))) {
|
||||
bch->inst.lock(bch->inst.privat, 0);
|
||||
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
|
||||
dev_kfree_skb(bch->next_skb);
|
||||
|
@ -1656,7 +1656,7 @@ isar_down(mISDNinstance_t *inst, struct sk_buff *skb)
|
|||
test_and_clear_bit(BC_FLG_ACTIV, &bch->Flag);
|
||||
bch->inst.unlock(bch->inst.privat);
|
||||
skb_trim(skb, 0);
|
||||
if (hh->prim != (MGR_DISCONNECT | REQUEST))
|
||||
if (hh->prim != (PH_CONTROL | REQUEST))
|
||||
if (!mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, 0, skb))
|
||||
return(0);
|
||||
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
|
||||
|
|
|
@ -2313,7 +2313,7 @@ new_udss1(mISDNstack_t *st, mISDN_pid_t *pid)
|
|||
nl3->dummy->l3 = nl3;
|
||||
nl3->dummy->t303skb = NULL;
|
||||
L3InitTimer(nl3->dummy, &nl3->dummy->timer);
|
||||
sprintf(nl3->inst.name, "DSS1 %d", st->id);
|
||||
sprintf(nl3->inst.name, "DSS1 %x", st->id >> 8);
|
||||
nl3->p_mgr = dss1man;
|
||||
list_add_tail(&nl3->list, &u_dss1.ilist);
|
||||
err = u_dss1.ctrl(&nl3->inst, MGR_NEWENTITY | REQUEST, NULL);
|
||||
|
@ -2354,7 +2354,7 @@ udss1_manager(void *data, u_int prim, void *arg) {
|
|||
mISDNinstance_t *inst = data;
|
||||
layer3_t *l3l;
|
||||
|
||||
if (debug & 0x1000)
|
||||
if (debug & MISDN_DEBUG_MANAGER)
|
||||
printk(KERN_DEBUG "udss1_manager data:%p prim:%x arg:%p\n", data, prim, arg);
|
||||
if (!data)
|
||||
return(-EINVAL);
|
||||
|
@ -2391,7 +2391,7 @@ udss1_manager(void *data, u_int prim, void *arg) {
|
|||
#endif
|
||||
case MGR_RELEASE | INDICATION:
|
||||
case MGR_UNREGLAYER | REQUEST:
|
||||
if (debug & 0x1000)
|
||||
if (debug & MISDN_DEBUG_MANAGER)
|
||||
printk(KERN_DEBUG "release_udss1 id %x\n", l3l->inst.st->id);
|
||||
release_udss1(l3l);
|
||||
break;
|
||||
|
|
|
@ -648,7 +648,7 @@ new_l1(mISDNstack_t *st, mISDN_pid_t *pid) {
|
|||
}
|
||||
switch(pid->protocol[1]) {
|
||||
case ISDN_PID_L1_TE_S0:
|
||||
sprintf(nl1->inst.name, "l1TES0 %d", st->id);
|
||||
sprintf(nl1->inst.name, "l1TES0 %x", st->id >> 8);
|
||||
nl1->l1m.fsm = &l1fsm_s;
|
||||
nl1->l1m.state = ST_L1_F3;
|
||||
nl1->Flags = 0;
|
||||
|
|
|
@ -187,10 +187,12 @@ l2down_create(layer2_t *l2, u_int prim, int dinfo, int len, void *arg)
|
|||
return(err);
|
||||
}
|
||||
|
||||
#ifdef OBSOLATE
|
||||
static int
|
||||
l2_chain_down(mISDNinstance_t *inst, struct sk_buff *skb) {
|
||||
return(l2down_raw(inst->privat, skb));
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ph_data_confirm(mISDNinstance_t *inst, mISDN_head_t *hh, struct sk_buff *skb) {
|
||||
|
@ -1833,15 +1835,24 @@ ph_data_indication(layer2_t *l2, mISDN_head_t *hh, struct sk_buff *skb) {
|
|||
}
|
||||
psapi >>= 2;
|
||||
ptei >>= 1;
|
||||
if ((psapi != l2->sapi) && (psapi != TEI_SAPI))
|
||||
return(ret);
|
||||
if ((psapi != l2->sapi) && (psapi != TEI_SAPI)) {
|
||||
/* not our bussiness */
|
||||
printk(KERN_DEBUG "%s: sapi %d/%d sapi mismatch\n", __FUNCTION__,
|
||||
psapi, l2->sapi);
|
||||
dev_kfree_skb(skb);
|
||||
return(0);
|
||||
}
|
||||
if (ptei == GROUP_TEI) {
|
||||
if (psapi == TEI_SAPI) {
|
||||
hh->prim = MDL_UNITDATA | INDICATION;
|
||||
return(l2_tei(l2->tm, skb));
|
||||
}
|
||||
} else if ((ptei != l2->tei) || (psapi == TEI_SAPI)) {
|
||||
return(ret);
|
||||
/* not our bussiness */
|
||||
printk(KERN_DEBUG "%s: tei %d/%d sapi %d mismatch\n", __FUNCTION__,
|
||||
ptei, l2->tei, psapi);
|
||||
dev_kfree_skb(skb);
|
||||
return(0);
|
||||
}
|
||||
} else
|
||||
datap += l;
|
||||
|
@ -1966,6 +1977,8 @@ static int
|
|||
l2from_up(layer2_t *l2, struct sk_buff *skb, mISDN_head_t *hh) {
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (hh->addr & FLG_MSG_CLONED)
|
||||
return(l2down_raw(l2, skb));
|
||||
switch (hh->prim) {
|
||||
case (DL_DATA | REQUEST):
|
||||
ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_DATA, skb);
|
||||
|
@ -2135,7 +2148,7 @@ release_l2(layer2_t *l2)
|
|||
}
|
||||
|
||||
static int
|
||||
new_l2(mISDNstack_t *st, mISDN_pid_t *pid, layer2_t **newl2) {
|
||||
new_l2(mISDNstack_t *st, mISDN_pid_t *pid) {
|
||||
layer2_t *nl2;
|
||||
int err;
|
||||
u_char *p;
|
||||
|
@ -2160,7 +2173,7 @@ new_l2(mISDNstack_t *st, mISDN_pid_t *pid, layer2_t **newl2) {
|
|||
}
|
||||
switch(pid->protocol[2] & ~ISDN_PID_FEATURE_MASK) {
|
||||
case ISDN_PID_L2_LAPD_NET:
|
||||
sprintf(nl2->inst.name, "lapdn %x", st->id);
|
||||
sprintf(nl2->inst.name, "lapdn %x", st->id>>8);
|
||||
test_and_set_bit(FLG_LAPD, &nl2->flag);
|
||||
test_and_set_bit(FLG_LAPD_NET, &nl2->flag);
|
||||
test_and_set_bit(FLG_FIXED_TEI, &nl2->flag);
|
||||
|
@ -2178,7 +2191,7 @@ new_l2(mISDNstack_t *st, mISDN_pid_t *pid, layer2_t **newl2) {
|
|||
}
|
||||
break;
|
||||
case ISDN_PID_L2_LAPD:
|
||||
sprintf(nl2->inst.name, "lapd %x", st->id);
|
||||
sprintf(nl2->inst.name, "lapd %x", st->id>>8);
|
||||
test_and_set_bit(FLG_LAPD, &nl2->flag);
|
||||
test_and_set_bit(FLG_MOD128, &nl2->flag);
|
||||
test_and_set_bit(FLG_ORIG, &nl2->flag);
|
||||
|
@ -2201,7 +2214,7 @@ new_l2(mISDNstack_t *st, mISDN_pid_t *pid, layer2_t **newl2) {
|
|||
break;
|
||||
case ISDN_PID_L2_B_X75SLP:
|
||||
test_and_set_bit(FLG_LAPB, &nl2->flag);
|
||||
sprintf(nl2->inst.name, "lapb %x", st->id);
|
||||
sprintf(nl2->inst.name, "lapb %x", st->id >> 8);
|
||||
nl2->window = 7;
|
||||
nl2->maxlen = MAX_DATA_SIZE;
|
||||
nl2->T200 = 1000;
|
||||
|
@ -2272,11 +2285,10 @@ new_l2(mISDNstack_t *st, mISDN_pid_t *pid, layer2_t **newl2) {
|
|||
stp.down_headerlen = l2headersize(nl2, 0);
|
||||
isdnl2.ctrl(st, MGR_ADDSTPARA | REQUEST, &stp);
|
||||
}
|
||||
if (newl2)
|
||||
*newl2 = nl2;
|
||||
return(err);
|
||||
}
|
||||
|
||||
#ifdef OBSOLATE
|
||||
static int
|
||||
clone_l2(layer2_t *l2, mISDNinstance_t **new_ip) {
|
||||
int err;
|
||||
|
@ -2295,7 +2307,6 @@ clone_l2(layer2_t *l2, mISDNinstance_t **new_ip) {
|
|||
printk(KERN_ERR "clone l2 failed err(%d)\n", err);
|
||||
return(err);
|
||||
}
|
||||
#ifdef FIXME
|
||||
nl2->cloneif = nif;
|
||||
nif->func = l2from_down;
|
||||
nif->fdata = nl2;
|
||||
|
@ -2311,10 +2322,10 @@ clone_l2(layer2_t *l2, mISDNinstance_t **new_ip) {
|
|||
nl2->inst.down.func = l2_chain_down;
|
||||
nl2->inst.down.fdata = l2;
|
||||
nl2->inst.down.stat = IF_UP;
|
||||
#endif
|
||||
*new_ip = &nl2->inst;
|
||||
return(err);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
l2_status(layer2_t *l2, status_info_l2_t *si)
|
||||
|
@ -2383,7 +2394,7 @@ l2_manager(void *data, u_int prim, void *arg) {
|
|||
}
|
||||
}
|
||||
if (prim == (MGR_NEWLAYER | REQUEST))
|
||||
return(new_l2(data, arg, NULL));
|
||||
return(new_l2(data, arg));
|
||||
if (err) {
|
||||
if (debug & 0x1)
|
||||
printk(KERN_WARNING "l2_manager prim(%x) l2 no instance\n", prim);
|
||||
|
@ -2398,9 +2409,9 @@ l2_manager(void *data, u_int prim, void *arg) {
|
|||
l2l->maxlen = ((mISDN_stPara_t *)arg)->maxdatalen;
|
||||
case MGR_CLRSTPARA | INDICATION:
|
||||
break;
|
||||
#ifdef OBSOLATE
|
||||
case MGR_CLONELAYER | REQUEST:
|
||||
return(clone_l2(l2l, arg));
|
||||
#ifdef OBSOLATE
|
||||
case MGR_CONNECT | REQUEST:
|
||||
return(mISDN_ConnectIF(inst, arg));
|
||||
case MGR_SETIF | REQUEST:
|
||||
|
|
|
@ -543,8 +543,8 @@ setup_speedfax(sedl_fax *sf)
|
|||
sf->bch[1].Write_Reg = &WriteISAR;
|
||||
lock_dev(sf, 0);
|
||||
#ifdef SPIN_DEBUG
|
||||
printk(KERN_ERR "spin_lock_adr=%p now(%p)\n", &sf->lock.spin_adr, sf->lock.spin_adr);
|
||||
printk(KERN_ERR "busy_lock_adr=%p now(%p)\n", &sf->lock.busy_adr, sf->lock.busy_adr);
|
||||
printk(KERN_DEBUG "spin_lock_adr=%p now(%p)\n", &sf->lock.spin_adr, sf->lock.spin_adr);
|
||||
printk(KERN_DEBUG "busy_lock_adr=%p now(%p)\n", &sf->lock.busy_adr, sf->lock.busy_adr);
|
||||
#endif
|
||||
writereg(sf->addr, sf->isar, ISAR_IRQBIT, 0);
|
||||
writereg(sf->addr, sf->isac, ISAC_MASK, 0xFF);
|
||||
|
@ -606,8 +606,9 @@ speedfax_manager(void *data, u_int prim, void *arg) {
|
|||
int channel = -1;
|
||||
struct sk_buff *skb;
|
||||
|
||||
printk(KERN_DEBUG "%s: data:%p prim:%x arg:%p\n",
|
||||
__FUNCTION__, data, prim, arg);
|
||||
if (debug & MISDN_DEBUG_MANAGER)
|
||||
printk(KERN_DEBUG "%s: data:%p prim:%x arg:%p\n",
|
||||
__FUNCTION__, data, prim, arg);
|
||||
if (!data) {
|
||||
MGR_HASPROTOCOL_HANDLER(prim,arg,&speedfax)
|
||||
printk(KERN_ERR "speedfax_manager no data prim %x arg %p\n",
|
||||
|
@ -641,22 +642,17 @@ speedfax_manager(void *data, u_int prim, void *arg) {
|
|||
bch_set_para(&card->bch[channel], &inst->st->para);
|
||||
break;
|
||||
case MGR_UNREGLAYER | REQUEST:
|
||||
if (channel == 2) {
|
||||
// inst->down.fdata = &card->dch;
|
||||
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
||||
HW_DEACTIVATE, 0, NULL, 0))) {
|
||||
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
|
||||
HW_DEACTIVATE, 0, NULL, 0))) {
|
||||
if (channel == 2) {
|
||||
if (mISDN_ISAC_l1hw(inst, skb))
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
} else {
|
||||
// inst->down.fdata = &card->bch[channel];
|
||||
if ((skb = create_link_skb(MGR_DISCONNECT | REQUEST,
|
||||
0, 0, NULL, 0))) {
|
||||
} else {
|
||||
if (isar_down(inst, skb))
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
// speedfax.ctrl(inst->up.peer, MGR_DISCONNECT | REQUEST, &inst->up);
|
||||
} else
|
||||
printk(KERN_WARNING "no SKB in %s MGR_UNREGLAYER | REQUEST\n", __FUNCTION__);
|
||||
speedfax.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||
break;
|
||||
case MGR_CLRSTPARA | INDICATION:
|
||||
|
@ -774,6 +770,7 @@ static int __devinit setup_instance(sedl_fax *card)
|
|||
release_card(card);
|
||||
return(err);
|
||||
}
|
||||
speedfax.ctrl(card->dch.inst.st, MGR_STOPSTACK | REQUEST, NULL);
|
||||
for (i=0; i<2; i++) {
|
||||
err = speedfax.ctrl(card->dch.inst.st, MGR_NEWSTACK | REQUEST, &card->bch[i].inst);
|
||||
if (err) {
|
||||
|
@ -793,6 +790,7 @@ static int __devinit setup_instance(sedl_fax *card)
|
|||
speedfax.ctrl(card->dch.inst.st, MGR_DELSTACK | REQUEST, NULL);
|
||||
return(err);
|
||||
}
|
||||
speedfax.ctrl(card->dch.inst.st, MGR_STARTSTACK | REQUEST, NULL);
|
||||
printk(KERN_INFO "SpeedFax %d cards installed\n", sedl_cnt);
|
||||
return(0);
|
||||
}
|
||||
|
|
|
@ -45,7 +45,9 @@ get_stack_info(struct sk_buff *skb)
|
|||
}
|
||||
} else
|
||||
st = get_stack4id(hp->addr);
|
||||
printk(KERN_DEBUG "%s: addr(%08x) st(%p)\n", __FUNCTION__, hp->addr, st);
|
||||
if (core_debug & DEBUG_CORE_FUNC)
|
||||
printk(KERN_DEBUG "%s: addr(%08x) st(%p) id(%08x)\n", __FUNCTION__, hp->addr, st,
|
||||
st ? st->id : 0);
|
||||
if (!st) {
|
||||
hp->len = -ENODEV;
|
||||
return;
|
||||
|
@ -60,6 +62,14 @@ get_stack_info(struct sk_buff *skb)
|
|||
si->mgr = 0;
|
||||
memcpy(&si->pid, &st->pid, sizeof(mISDN_pid_t));
|
||||
memcpy(&si->para, &st->para, sizeof(mISDN_stPara_t));
|
||||
if (st->clone)
|
||||
si->clone = st->clone->id;
|
||||
else
|
||||
si->clone = 0;
|
||||
if (st->master)
|
||||
si->master = st->master->id;
|
||||
else
|
||||
si->master = 0;
|
||||
si->instcnt = 0;
|
||||
for (i = 0; i <= MAX_LAYER_NR; i++) {
|
||||
if (st->i_array[i]) {
|
||||
|
@ -103,11 +113,13 @@ get_free_stackid(mISDNstack_t *mst, int flag)
|
|||
while(id < CLONE_ID_MAX) {
|
||||
found = 0;
|
||||
id += CLONE_ID_INC;
|
||||
list_for_each_entry(st, &mISDN_stacklist, list) {
|
||||
st = mst->clone;
|
||||
while (st) {
|
||||
if (st->id == id) {
|
||||
found++;
|
||||
break;
|
||||
}
|
||||
st = st->clone;
|
||||
}
|
||||
if (!found)
|
||||
return(id);
|
||||
|
@ -142,9 +154,19 @@ get_stack4id(u_int id)
|
|||
list_for_each_entry(st, &mISDN_stacklist, list) {
|
||||
if (id == st->id)
|
||||
return(st);
|
||||
list_for_each_entry(cst, &st->childlist, list) {
|
||||
if (cst->id == id)
|
||||
return(cst);
|
||||
if ((id & FLG_CHILD_STACK) && ((id & MASTER_ID_MASK) == st->id)) {
|
||||
list_for_each_entry(cst, &st->childlist, list) {
|
||||
if (cst->id == id)
|
||||
return(cst);
|
||||
}
|
||||
}
|
||||
if ((id & FLG_CLONE_STACK) && ((id & MASTER_ID_MASK) == st->id)) {
|
||||
cst = st->clone;
|
||||
while (cst) {
|
||||
if (cst->id == id)
|
||||
return(cst);
|
||||
cst = cst->clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
|
@ -172,19 +194,19 @@ get_nextlayer(mISDNstack_t *st, u_int addr)
|
|||
mISDNinstance_t *inst=NULL;
|
||||
int layer = addr & LAYER_ID_MASK;
|
||||
|
||||
if (core_debug & DEBUG_CORE_FUNC)
|
||||
printk(KERN_DEBUG "%s: st(%08x) addr(%08x)\n", __FUNCTION__, st->id, addr);
|
||||
|
||||
if (!(addr & FLG_MSG_TARGET)) {
|
||||
switch(addr & MSG_DIR_MASK) {
|
||||
case FLG_MSG_DOWN:
|
||||
if (addr & FLG_MSG_CLONED) {
|
||||
|
||||
/* OK */
|
||||
} else
|
||||
layer -= LAYER_ID_INC;
|
||||
break;
|
||||
case FLG_MSG_UP:
|
||||
layer += LAYER_ID_INC;
|
||||
if (addr & FLG_MSG_CLONED) {
|
||||
/* OK */
|
||||
} else
|
||||
layer += LAYER_ID_INC;
|
||||
break;
|
||||
case MSG_TO_OWNER:
|
||||
break;
|
||||
|
@ -198,7 +220,9 @@ get_nextlayer(mISDNstack_t *st, u_int addr)
|
|||
return(NULL);
|
||||
}
|
||||
inst = st->i_array[layer];
|
||||
/* maybe more checks */
|
||||
if (core_debug & DEBUG_QUEUE_FUNC)
|
||||
printk(KERN_DEBUG "%s: st(%08x) addr(%08x) -> inst(%08x)\n",
|
||||
__FUNCTION__, st->id, addr, inst ? inst->id : 0);
|
||||
return(inst);
|
||||
}
|
||||
|
||||
|
@ -304,7 +328,7 @@ mISDN_queue_message(mISDNinstance_t *inst, u_int aflag, struct sk_buff *skb)
|
|||
mISDNstack_t *st = inst->st;
|
||||
u_int id;
|
||||
|
||||
if (core_debug & DEBUG_CORE_FUNC)
|
||||
if (core_debug & DEBUG_QUEUE_FUNC)
|
||||
printk(KERN_DEBUG "%s(%08x, %x, prim(%x))\n", __FUNCTION__,
|
||||
inst->id, aflag, hh->prim);
|
||||
if (aflag & FLG_MSG_TARGET) {
|
||||
|
@ -314,24 +338,31 @@ mISDN_queue_message(mISDNinstance_t *inst, u_int aflag, struct sk_buff *skb)
|
|||
}
|
||||
if ((aflag & MSG_DIR_MASK) == FLG_MSG_DOWN) {
|
||||
if (inst->parent) {
|
||||
st = inst->parent->st;
|
||||
id = id | FLG_MSG_CLONED;
|
||||
inst = inst->parent;
|
||||
st = inst->st;
|
||||
id = (inst->id & INST_ID_MASK) | FLG_MSG_TARGET | FLG_MSG_CLONED | FLG_MSG_DOWN;
|
||||
}
|
||||
}
|
||||
if (!st)
|
||||
return(-EINVAL);
|
||||
if (st->id == 0 || test_bit(mISDN_STACK_ABORT, &st->status))
|
||||
return(-EBUSY);
|
||||
if (inst->id == 0) { /* instance is not initialised */
|
||||
if (!(aflag & FLG_MSG_TARGET)) {
|
||||
id &= INST_ID_MASK;
|
||||
id |= (st->id & INST_ID_MASK) | aflag | FLG_INSTANCE;
|
||||
}
|
||||
}
|
||||
if (test_bit(mISDN_STACK_KILLED, &st->status))
|
||||
return(-EBUSY);
|
||||
if (test_bit(mISDN_STACK_STOPPED, &st->status))
|
||||
return(-EBUSY);
|
||||
if ((st->id & STACK_ID_MASK) != (id & STACK_ID_MASK)) {
|
||||
int_errtxt("stack id not match st(%08x) id(%08x)", st->id, id);
|
||||
int_errtxt("stack id not match st(%08x) id(%08x) inst(%08x) aflag(%08x) prim(%x)",
|
||||
st->id, id, inst->id, aflag, hh->prim);
|
||||
}
|
||||
hh->addr = id;
|
||||
skb_queue_tail(&st->msgq, skb);
|
||||
wake_up_interruptible(&st->workq);
|
||||
if (!test_bit(mISDN_STACK_STOPPED, &st->status))
|
||||
wake_up_interruptible(&st->workq);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -363,12 +394,16 @@ mISDNStackd(void *data)
|
|||
printk(KERN_DEBUG "mISDNStackd started for id(%08x)\n", st->id);
|
||||
test_and_clear_bit(mISDN_STACK_INIT, &st->status);
|
||||
for (;;) {
|
||||
struct sk_buff *skb;
|
||||
struct sk_buff *skb, *c_skb;
|
||||
mISDN_head_t *hh;
|
||||
|
||||
while ((skb = skb_dequeue(&st->msgq))) {
|
||||
while ((!test_bit(mISDN_STACK_STOPPED, &st->status)) &&
|
||||
((skb = skb_dequeue(&st->msgq)))) {
|
||||
mISDNinstance_t *inst;
|
||||
|
||||
#ifdef MISDN_MSG_STATS
|
||||
st->msg_cnt++;
|
||||
#endif
|
||||
hh = mISDN_HEAD_P(skb);
|
||||
if ((hh->addr & MSG_DIR_MASK) == MSG_BROADCAST) {
|
||||
do_broadcast(st, skb);
|
||||
|
@ -376,19 +411,50 @@ mISDNStackd(void *data)
|
|||
}
|
||||
inst = get_nextlayer(st, hh->addr);
|
||||
if (!inst) {
|
||||
int_errtxt("%s: st(%08x) no instance for addr(%08x) prim(%x) dinfo(%x)", __FUNCTION__,
|
||||
st->id, hh->addr, hh->prim, hh->dinfo);
|
||||
if (core_debug & DEBUG_MSG_THREAD_ERR)
|
||||
printk(KERN_DEBUG "%s: st(%08x) no instance for addr(%08x) prim(%x) dinfo(%x)\n",
|
||||
__FUNCTION__, st->id, hh->addr, hh->prim, hh->dinfo);
|
||||
dev_kfree_skb(skb);
|
||||
continue;
|
||||
}
|
||||
if (inst->clone && ((hh->addr & MSG_DIR_MASK) == FLG_MSG_UP)) {
|
||||
u_int id = (inst->clone->id & INST_ID_MASK) | FLG_MSG_TARGET | FLG_MSG_CLONED | FLG_MSG_UP;
|
||||
|
||||
#ifdef MISDN_MSG_STATS
|
||||
st->clone_cnt++;
|
||||
#endif
|
||||
c_skb = skb_copy(skb, GFP_KERNEL);
|
||||
if (c_skb) {
|
||||
if (core_debug & DEBUG_MSG_THREAD_INFO)
|
||||
printk(KERN_DEBUG "%s: inst(%08x) msg clone msg to(%08x) caddr(%08x) prim(%x)\n",
|
||||
__FUNCTION__, inst->id, inst->clone->id, id, hh->prim);
|
||||
err = mISDN_queue_message(inst->clone, id, c_skb);
|
||||
if (err) {
|
||||
if (core_debug & DEBUG_MSG_THREAD_ERR)
|
||||
printk(KERN_DEBUG "%s: clone instance(%08x) cannot queue msg(%08x) err(%d)\n",
|
||||
__FUNCTION__, inst->clone->id, id, err);
|
||||
dev_kfree_skb(c_skb);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_WARNING "%s OOM on msg cloning inst(%08x) caddr(%08x) prim(%x) len(%d)\n",
|
||||
__FUNCTION__, inst->id, id, hh->prim, skb->len);
|
||||
}
|
||||
}
|
||||
if (core_debug & DEBUG_MSG_THREAD_INFO)
|
||||
printk(KERN_DEBUG "%s: inst(%08x) msg call addr(%08x) prim(%x)\n",
|
||||
__FUNCTION__, inst->id, hh->addr, hh->prim);
|
||||
if (!inst->function) {
|
||||
int_errtxt("%s: instance(%08x) no function", __FUNCTION__, inst->id);
|
||||
if (core_debug & DEBUG_MSG_THREAD_ERR)
|
||||
printk(KERN_DEBUG "%s: instance(%08x) no function\n",
|
||||
__FUNCTION__, inst->id);
|
||||
dev_kfree_skb(skb);
|
||||
continue;
|
||||
}
|
||||
err = inst->function(inst, skb);
|
||||
if (err) {
|
||||
int_errtxt("%s: instance(%08x)->function return(%d)", __FUNCTION__, inst->id, err);
|
||||
if (core_debug & DEBUG_MSG_THREAD_ERR)
|
||||
printk(KERN_DEBUG "%s: instance(%08x)->function return(%d)\n",
|
||||
__FUNCTION__, inst->id, err);
|
||||
dev_kfree_skb(skb);
|
||||
continue;
|
||||
}
|
||||
|
@ -397,8 +463,22 @@ mISDNStackd(void *data)
|
|||
break;
|
||||
if (st->notify != NULL)
|
||||
up(st->notify);
|
||||
interruptible_sleep_on(&st->workq);
|
||||
#ifdef MISDN_MSG_STATS
|
||||
st->sleep_cnt++;
|
||||
#endif
|
||||
wait_event_interruptible(st->workq, ((!skb_queue_empty(&st->msgq)) ||
|
||||
test_bit(mISDN_STACK_ABORT, &st->status)));
|
||||
if (test_bit(mISDN_STACK_STOPPED, &st->status)) {
|
||||
wait_event_interruptible(st->workq, (!test_bit(mISDN_STACK_STOPPED, &st->status)));
|
||||
#ifdef MISDN_MSG_STATS
|
||||
st->stopped_cnt++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#ifdef MISDN_MSG_STATS
|
||||
printk(KERN_DEBUG "mISDNStackd daemon for id(%08x) proceed %d msg %d clone %d sleep %d stopped\n",
|
||||
st->id, st->msg_cnt, st->clone_cnt, st->sleep_cnt, st->stopped_cnt);
|
||||
#endif
|
||||
printk(KERN_DEBUG "mISDNStackd daemon for id(%08x) killed now\n", st->id);
|
||||
test_and_set_bit(mISDN_STACK_KILLED, &st->status);
|
||||
discard_queue(&st->msgq);
|
||||
|
@ -421,6 +501,7 @@ new_stack(mISDNstack_t *master, mISDNinstance_t *inst)
|
|||
return(NULL);
|
||||
}
|
||||
memset(newst, 0, sizeof(mISDNstack_t));
|
||||
INIT_LIST_HEAD(&newst->list);
|
||||
INIT_LIST_HEAD(&newst->childlist);
|
||||
INIT_LIST_HEAD(&newst->prereg);
|
||||
init_waitqueue_head(&newst->workq);
|
||||
|
@ -428,7 +509,13 @@ new_stack(mISDNstack_t *master, mISDNinstance_t *inst)
|
|||
test_and_set_bit(mISDN_STACK_INIT, &newst->status);
|
||||
if (!master) {
|
||||
if (inst && inst->st) {
|
||||
master = inst->st;
|
||||
while(master->clone)
|
||||
master = master->clone;
|
||||
newst->id = get_free_stackid(inst->st, FLG_CLONE_STACK);
|
||||
newst->master = master;
|
||||
master->clone = newst;
|
||||
master = NULL;
|
||||
} else {
|
||||
newst->id = get_free_stackid(NULL, 0);
|
||||
}
|
||||
|
@ -438,17 +525,30 @@ new_stack(mISDNstack_t *master, mISDNinstance_t *inst)
|
|||
newst->mgr = inst;
|
||||
if (master) {
|
||||
list_add_tail(&newst->list, &master->childlist);
|
||||
} else {
|
||||
} else if (!(newst->id & FLG_CLONE_STACK)) {
|
||||
list_add_tail(&newst->list, &mISDN_stacklist);
|
||||
}
|
||||
if (core_debug & DEBUG_CORE_FUNC)
|
||||
printk(KERN_DEBUG "Stack id %x added\n", newst->id);
|
||||
if (inst)
|
||||
if (inst) {
|
||||
inst->st = newst;
|
||||
}
|
||||
kernel_thread(mISDNStackd, (void *)newst, 0);
|
||||
return(newst);
|
||||
}
|
||||
|
||||
int
|
||||
mISDN_start_stop(mISDNstack_t *st, int start)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (start) {
|
||||
ret = test_and_clear_bit(mISDN_STACK_STOPPED, &st->status);
|
||||
wake_up_interruptible(&st->workq);
|
||||
} else
|
||||
ret = test_and_set_bit(mISDN_STACK_STOPPED, &st->status);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
release_layers(mISDNstack_t *st, u_int prim)
|
||||
|
@ -546,7 +646,7 @@ delete_stack(mISDNstack_t *st)
|
|||
if (st->thread) {
|
||||
st->notify = &sem;
|
||||
test_and_set_bit(mISDN_STACK_ABORT, &st->status);
|
||||
wake_up_interruptible(&st->workq);
|
||||
mISDN_start_stop(st, 1);
|
||||
down(&sem);
|
||||
st->notify = NULL;
|
||||
}
|
||||
|
@ -572,7 +672,15 @@ release_stack(mISDNstack_t *st) {
|
|||
return(err);
|
||||
}
|
||||
}
|
||||
|
||||
if (st->clone) {
|
||||
st->clone->master = st->master;
|
||||
}
|
||||
if (st->master) {
|
||||
st->master->clone = st->clone;
|
||||
} else if (st->clone) { /* no master left -> delete clone too */
|
||||
delete_stack(st->clone);
|
||||
st->clone = NULL;
|
||||
}
|
||||
if ((err = delete_stack(st)))
|
||||
return(err);
|
||||
|
||||
|
@ -745,6 +853,19 @@ unregister_instance(mISDNinstance_t *inst) {
|
|||
if (inst->st && (inst->st->mgr != inst))
|
||||
inst->st = NULL;
|
||||
}
|
||||
if (inst->parent) { /*we are cloned */
|
||||
inst->parent->clone = inst->clone;
|
||||
if (inst->clone)
|
||||
inst->clone->parent = inst->parent;
|
||||
inst->clone = NULL;
|
||||
inst->parent = NULL;
|
||||
} else if (inst->clone) {
|
||||
/* deleting the top level master of a clone */
|
||||
/* FIXME: should be handled somehow, maybe unregister the clone */
|
||||
int_errtxt("removed master(%08x) of clone(%08x)", inst->id, inst->clone->id);
|
||||
inst->clone->parent = NULL;
|
||||
inst->clone = NULL;
|
||||
}
|
||||
if (inst->list.prev && inst->list.next)
|
||||
list_del_init(&inst->list);
|
||||
else
|
||||
|
@ -762,7 +883,7 @@ copy_pid(mISDN_pid_t *dpid, mISDN_pid_t *spid, u_char *pbuf)
|
|||
u_int i, off;
|
||||
|
||||
memcpy(dpid, spid, sizeof(mISDN_pid_t));
|
||||
if (spid->pbuf) {
|
||||
if (spid->pbuf && spid->maxplen) {
|
||||
if (!pbuf) {
|
||||
int_error();
|
||||
return(-ENOMEM);
|
||||
|
|
|
@ -375,13 +375,13 @@ create_layer(mISDNdevice_t *dev, struct sk_buff *skb)
|
|||
devicelayer_t *nl;
|
||||
mISDNobject_t *obj;
|
||||
mISDNinstance_t *inst = NULL;
|
||||
mISDN_head_t *hp;
|
||||
mISDN_head_t *hp;
|
||||
|
||||
hp = mISDN_HEAD_P(skb);
|
||||
linfo = (layer_info_t *)skb->data;
|
||||
if (!(st = get_stack4id(linfo->st))) {
|
||||
/* should be changed */
|
||||
int_error();
|
||||
printk(KERN_WARNING "%s: no stack found for id(%08x)\n", __FUNCTION__, linfo->st);
|
||||
return(-ENODEV);
|
||||
}
|
||||
if (linfo->object_id != -1) {
|
||||
|
@ -402,7 +402,64 @@ create_layer(mISDNdevice_t *dev, struct sk_buff *skb)
|
|||
printk(KERN_WARNING "%s: no inst found\n", __FUNCTION__);
|
||||
return(-EINVAL);
|
||||
}
|
||||
} else if ((inst = getlayer4lay(st, linfo->pid.layermask))) {
|
||||
} else if (linfo->extentions & EXT_INST_CLONE) {
|
||||
mISDN_pid_t *pid;
|
||||
|
||||
inst = get_instance4id(linfo->parent);
|
||||
if (!inst) {
|
||||
printk(KERN_WARNING "%s: no parent inst found\n", __FUNCTION__);
|
||||
return(-EINVAL);
|
||||
}
|
||||
if (!(inst->extentions & EXT_INST_CLONE)) {
|
||||
printk(KERN_WARNING "%s: inst(%08x) ext(%x) is not cloneable\n",
|
||||
__FUNCTION__, inst->id, inst->extentions);
|
||||
return(-ENOSYS);
|
||||
}
|
||||
for(i=0; i<=MAX_LAYER_NR; i++)
|
||||
if (!st->i_array[i])
|
||||
break;
|
||||
if (i > MAX_LAYER_NR) {
|
||||
printk(KERN_WARNING "%s: no free instance slot in stack id(%08x)\n",
|
||||
__FUNCTION__, st->id);
|
||||
return(-EBUSY);
|
||||
}
|
||||
pid = kmalloc(sizeof(mISDN_pid_t), GFP_ATOMIC);
|
||||
if (!pid) {
|
||||
printk(KERN_ERR "kmalloc pid failed\n");
|
||||
return(-ENOMEM);
|
||||
}
|
||||
memset(pid, 0, sizeof(mISDN_pid_t));
|
||||
if (inst->pid.pbuf && inst->pid.maxplen) {
|
||||
pid->pbuf = kmalloc(inst->pid.maxplen, GFP_ATOMIC);
|
||||
if (!pid->pbuf) {
|
||||
kfree(pid);
|
||||
printk(KERN_ERR "kmalloc pid->pbuf failed\n");
|
||||
return(-ENOMEM);
|
||||
}
|
||||
memset(pid->pbuf, 0, inst->pid.maxplen);
|
||||
}
|
||||
copy_pid(pid, &inst->pid, pid->pbuf);
|
||||
ret = inst->obj->own_ctrl(st, MGR_NEWLAYER | REQUEST, pid);
|
||||
if (pid->pbuf)
|
||||
kfree(pid->pbuf);
|
||||
kfree(pid);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "%s: MGR_NEWLAYER | REQUEST for clone returns %d\n", __FUNCTION__, ret);
|
||||
return(ret);
|
||||
}
|
||||
if (!st->i_array[i]) {
|
||||
int_error();
|
||||
return(-EINVAL);
|
||||
} else {
|
||||
while (inst->clone)
|
||||
inst = inst->clone;
|
||||
inst->clone = st->i_array[i];
|
||||
st->i_array[i]->parent = inst;
|
||||
inst = st->i_array[i];
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if ((inst = getlayer4lay(st, linfo->pid.layermask))) {
|
||||
if (!(linfo->extentions & EXT_INST_MIDDLE)) {
|
||||
printk(KERN_WARNING
|
||||
"mISDN create_layer st(%x) LM(%x) inst not empty(%08x)\n",
|
||||
|
@ -410,12 +467,15 @@ create_layer(mISDNdevice_t *dev, struct sk_buff *skb)
|
|||
return(-EBUSY);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!(nl = kmalloc(sizeof(devicelayer_t), GFP_ATOMIC))) {
|
||||
printk(KERN_ERR "kmalloc devicelayer failed\n");
|
||||
return(-ENOMEM);
|
||||
}
|
||||
memset(nl, 0, sizeof(devicelayer_t));
|
||||
if (st)
|
||||
if (inst)
|
||||
nl->id = get_new_devicelayer_id(dev, inst->id);
|
||||
else if (st)
|
||||
nl->id = get_new_devicelayer_id(dev, st->id);
|
||||
else
|
||||
nl->id = get_new_devicelayer_id(dev, 0);
|
||||
|
@ -426,36 +486,39 @@ create_layer(mISDNdevice_t *dev, struct sk_buff *skb)
|
|||
}
|
||||
if (device_debug & DEBUG_MGR_FUNC)
|
||||
printk(KERN_DEBUG
|
||||
"mISDN create_layer LM(%x) nl(%p:%08x) nl inst(%p)\n",
|
||||
linfo->pid.layermask, nl, nl->id, &nl->inst);
|
||||
"mISDN create_layer LM(%x) nl(%p:%08x) nl->inst(%p) inst(%p)\n",
|
||||
linfo->pid.layermask, nl, nl->id, &nl->inst, inst);
|
||||
nl->dev = dev;
|
||||
mISDN_init_instance(&nl->inst, &udev_obj, nl, from_up_down);
|
||||
memcpy(&nl->inst.pid, &linfo->pid, sizeof(mISDN_pid_t));
|
||||
strcpy(nl->inst.name, linfo->name);
|
||||
nl->inst.extentions = linfo->extentions;
|
||||
for (i=0; i<= MAX_LAYER_NR; i++) {
|
||||
if (linfo->pid.layermask & ISDN_LAYER(i)) {
|
||||
if (st && (st->pid.protocol[i] == ISDN_PID_NONE)) {
|
||||
st->pid.protocol[i] = linfo->pid.protocol[i];
|
||||
nl->lm_st |= ISDN_LAYER(i);
|
||||
list_add_tail(&nl->list, &dev->layerlist);
|
||||
if (!inst) {
|
||||
mISDN_init_instance(&nl->inst, &udev_obj, nl, from_up_down);
|
||||
memcpy(&nl->inst.pid, &linfo->pid, sizeof(mISDN_pid_t));
|
||||
strcpy(nl->inst.name, linfo->name);
|
||||
nl->inst.extentions = linfo->extentions;
|
||||
for (i=0; i<= MAX_LAYER_NR; i++) {
|
||||
if (linfo->pid.layermask & ISDN_LAYER(i)) {
|
||||
if (st && (st->pid.protocol[i] == ISDN_PID_NONE)) {
|
||||
st->pid.protocol[i] = linfo->pid.protocol[i];
|
||||
nl->lm_st |= ISDN_LAYER(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (st && (linfo->extentions & EXT_INST_MGR)) {
|
||||
st->mgr = &nl->inst;
|
||||
test_and_set_bit(FLG_MGR_OWNSTACK, &nl->Flags);
|
||||
}
|
||||
if (st)
|
||||
nl->inst.obj->ctrl(st, MGR_ADDLAYER | REQUEST, &nl->inst);
|
||||
} else {
|
||||
nl->slave = inst;
|
||||
nl->inst.extentions |= EXT_INST_UNUSED;
|
||||
}
|
||||
if (st && (linfo->extentions & EXT_INST_MGR)) {
|
||||
st->mgr = &nl->inst;
|
||||
test_and_set_bit(FLG_MGR_OWNSTACK, &nl->Flags);
|
||||
}
|
||||
list_add_tail(&nl->list, &dev->layerlist);
|
||||
if (st)
|
||||
nl->inst.obj->ctrl(st, MGR_ADDLAYER | REQUEST, &nl->inst);
|
||||
skb_trim(skb, 0);
|
||||
memcpy(skb_put(skb, sizeof(nl->id)), &nl->id, sizeof(nl->id));
|
||||
if (inst) {
|
||||
nl->slave = inst;
|
||||
if (inst)
|
||||
memcpy(skb_put(skb, sizeof(inst->id)), &inst->id, sizeof(inst->id));
|
||||
} else {
|
||||
else
|
||||
memset(skb_put(skb, sizeof(nl->id)), 0, sizeof(nl->id));
|
||||
}
|
||||
return(8);
|
||||
}
|
||||
|
||||
|
@ -521,7 +584,9 @@ del_layer(devicelayer_t *dl)
|
|||
}
|
||||
dl->id = 0;
|
||||
list_del(&dl->list);
|
||||
udev_obj.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||
if (!(inst->extentions & EXT_INST_UNUSED)) {
|
||||
udev_obj.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||
}
|
||||
if (test_and_clear_bit(FLG_MGR_OWNSTACK, &dl->Flags)) {
|
||||
if (dl->inst.st) {
|
||||
del_stack(get_devstack(dev, dl->inst.st->id));
|
||||
|
@ -531,6 +596,7 @@ del_layer(devicelayer_t *dl)
|
|||
return(0);
|
||||
}
|
||||
|
||||
#ifdef OBSOLATE
|
||||
static mISDNinstance_t *
|
||||
clone_instance(devicelayer_t *dl, mISDNstack_t *st, mISDNinstance_t *peer)
|
||||
{
|
||||
|
@ -556,7 +622,6 @@ clone_instance(devicelayer_t *dl, mISDNstack_t *st, mISDNinstance_t *peer)
|
|||
return(dl->slave);
|
||||
}
|
||||
|
||||
#ifdef OBSOLATE
|
||||
static int
|
||||
remove_if(devicelayer_t *dl, int stat) {
|
||||
mISDNif_t *hif,*phif,*shif;
|
||||
|
@ -1046,6 +1111,10 @@ get_layer_info(struct sk_buff *skb)
|
|||
li->id = inst->id;
|
||||
if (inst->st)
|
||||
li->st = inst->st->id;
|
||||
if (inst->parent)
|
||||
li->parent = inst->parent->id;
|
||||
if (inst->clone)
|
||||
li->clone = inst->clone->id;
|
||||
memcpy(&li->pid, &inst->pid, sizeof(mISDN_pid_t));
|
||||
hp->len = sizeof(layer_info_t);
|
||||
skb_put(skb, hp->len);
|
||||
|
|
|
@ -1300,9 +1300,9 @@ dte_manager(void *data, u_int prim, void *arg) {
|
|||
}
|
||||
break;
|
||||
case MGR_CLRSTPARA | INDICATION:
|
||||
#ifdef OBSOLATE
|
||||
case MGR_CLONELAYER | REQUEST:
|
||||
break;
|
||||
#ifdef OBSOLATE
|
||||
case MGR_CONNECT | REQUEST:
|
||||
return(mISDN_ConnectIF(inst, arg));
|
||||
case MGR_SETIF | REQUEST:
|
||||
|
|
|
@ -9,16 +9,6 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
|
||||
/* primitives for information exchange
|
||||
* generell format
|
||||
* <8 bit reserved>
|
||||
* <4 bit flags>
|
||||
* <4 bit layer>
|
||||
* <8 bit command>
|
||||
* <8 bit subcommand>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* ABI Version 32 bit
|
||||
*
|
||||
|
@ -36,6 +26,19 @@
|
|||
#define MISDN_REVISION "$Revision$"
|
||||
#define MISDN_DATE "$Date$"
|
||||
|
||||
/* collect some statistics about the message queues */
|
||||
#define MISDN_MSG_STATS
|
||||
|
||||
/* primitives for information exchange
|
||||
* generell format
|
||||
* <8 bit reserved>
|
||||
* <4 bit flags>
|
||||
* <4 bit layer>
|
||||
* <8 bit command>
|
||||
* <8 bit subcommand>
|
||||
*
|
||||
*/
|
||||
|
||||
/* SUBCOMMANDS */
|
||||
#define REQUEST 0x80
|
||||
#define CONFIRM 0x81
|
||||
|
@ -66,15 +69,17 @@
|
|||
#define MGR_GETLAYERID 0x0f2200
|
||||
#define MGR_NEWLAYER 0x0f2300
|
||||
#define MGR_DELLAYER 0x0f2400
|
||||
#define MGR_CLONELAYER 0x0f2500
|
||||
//#define MGR_CLONELAYER 0x0f2500
|
||||
//#define MGR_GETIF 0x0f3100
|
||||
//#define MGR_CONNECT 0x0f3200
|
||||
#define MGR_DISCONNECT 0x0f3300
|
||||
//#define MGR_DISCONNECT 0x0f3300
|
||||
//#define MGR_SETIF 0x0f3400
|
||||
//#define MGR_ADDIF 0x0f3500
|
||||
//#define MGR_QUEUEIF 0x0f3600
|
||||
#define MGR_CTRLREADY 0x0f4100
|
||||
#define MGR_STACKREADY 0x0f4200
|
||||
#define MGR_STOPSTACK 0x0f4300
|
||||
#define MGR_STARTSTACK 0x0f4400
|
||||
#define MGR_RELEASE 0x0f4500
|
||||
#define MGR_GETDEVICE 0x0f5100
|
||||
#define MGR_DELDEVICE 0x0f5200
|
||||
|
@ -498,15 +503,16 @@
|
|||
#define CHANNEL_EXT_PCM 0x01000000
|
||||
#define CHANNEL_EXT_REV 0x02000000
|
||||
|
||||
/* interface extentions */
|
||||
/* instance/stack extentions */
|
||||
#define EXT_STACK_CLONE 0x00000001
|
||||
#define EXT_INST_CLONE 0x00000100
|
||||
#define EXT_INST_MGR 0x00000200
|
||||
#define EXT_INST_MIDDLE 0x00000400
|
||||
#define EXT_IF_CHAIN 0x00010000
|
||||
#define EXT_IF_EXCLUSIV 0x00020000
|
||||
#define EXT_IF_CREATE 0x00040000
|
||||
#define EXT_IF_SPLIT 0x00080000
|
||||
#define EXT_INST_UNUSED 0x00000800
|
||||
//#define EXT_IF_CHAIN 0x00010000
|
||||
//#define EXT_IF_EXCLUSIV 0x00020000
|
||||
//#define EXT_IF_CREATE 0x00040000
|
||||
//#define EXT_IF_SPLIT 0x00080000
|
||||
|
||||
/* stack status flag (bit position) */
|
||||
#define mISDN_STACK_INIT 0
|
||||
|
@ -580,6 +586,8 @@ typedef struct _stack_info {
|
|||
mISDN_stPara_t para;
|
||||
u_int extentions;
|
||||
u_int mgr;
|
||||
u_int master;
|
||||
u_int clone;
|
||||
int instcnt;
|
||||
int inst[MAX_LAYER_NR +1];
|
||||
int childcnt;
|
||||
|
@ -592,6 +600,8 @@ typedef struct _layer_info {
|
|||
int extentions;
|
||||
u_int id;
|
||||
u_int st;
|
||||
u_int clone;
|
||||
u_int parent;
|
||||
mISDN_pid_t pid;
|
||||
} layer_info_t;
|
||||
|
||||
|
@ -765,9 +775,17 @@ struct _mISDNstack {
|
|||
struct semaphore *notify;
|
||||
wait_queue_head_t workq;
|
||||
struct sk_buff_head msgq;
|
||||
#ifdef MISDN_MSG_STATS
|
||||
u_int msg_cnt;
|
||||
u_int sleep_cnt;
|
||||
u_int clone_cnt;
|
||||
u_int stopped_cnt;
|
||||
#endif
|
||||
mISDNinstance_t *i_array[MAX_LAYER_NR + 1];
|
||||
struct list_head prereg;
|
||||
mISDNinstance_t *mgr;
|
||||
mISDNstack_t *master;
|
||||
mISDNstack_t *clone;
|
||||
struct list_head childlist;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue