first step move to message queue driven desgin (DO NOT USE THIS VERSION)

This commit is contained in:
Karsten Keil 2005-05-07 21:04:11 +00:00
parent 00c2a28955
commit 4cbd60f063
30 changed files with 899 additions and 745 deletions

View File

@ -30,7 +30,7 @@ endif
ifdef CONFIG_MISDN_SPEEDFAX
obj-$(CONFIG_MISDN_DRV) += sedlfax.o
obj-$(CONFIG_MISDN_DRV) += faxl3.o
# obj-$(CONFIG_MISDN_DRV) += faxl3.o
endif
ifdef CONFIG_MISDN_W6692

View File

@ -1269,7 +1269,7 @@ AppPlciLinkUp(AppPlci_t *aplci)
}
capidebug(CAPI_DBG_NCCI, "AppPlciLinkUp aplci->link(%p)", aplci->link);
memset(&aplci->link->inst.pid, 0, sizeof(mISDN_pid_t));
aplci->link->inst.data = aplci;
aplci->link->inst.privat = aplci;
aplci->link->inst.pid.layermask = ISDN_LAYER(4);
aplci->link->inst.pid.protocol[4] = ISDN_PID_L4_B_CAPI20;
if (pid.protocol[3] == ISDN_PID_L3_B_TRANS) {
@ -1370,17 +1370,15 @@ get_single_NCCI(AppPlci_t *aplci)
}
static int
PL_l3l4(mISDNif_t *hif, struct sk_buff *skb)
PL_l3l4(mISDNinstance_t *inst, struct sk_buff *skb)
{
AppPlci_t *aplci;
Ncci_t *ncci;
int ret = -EINVAL;
mISDN_head_t *hh;
if (!hif || !skb)
return(ret);
hh = mISDN_HEAD_P(skb);
aplci = hif->fdata;
aplci = inst->privat;
if (!aplci)
return(-EINVAL);
ncci = get_single_NCCI(aplci);
@ -1401,7 +1399,7 @@ PL_l3l4(mISDNif_t *hif, struct sk_buff *skb)
}
static int
PL_l3l4mux(mISDNif_t *hif, struct sk_buff *skb)
PL_l3l4mux(mISDNinstance_t *inst, struct sk_buff *skb)
{
AppPlci_t *aplci;
Ncci_t *ncci;
@ -1409,10 +1407,8 @@ PL_l3l4mux(mISDNif_t *hif, struct sk_buff *skb)
mISDN_head_t *hh;
__u32 addr;
if (!hif || !skb)
return(ret);
hh = mISDN_HEAD_P(skb);
aplci = hif->fdata;
aplci = inst->privat;
if (!aplci)
return(-EINVAL);
@ -1464,13 +1460,14 @@ AppPlcimISDN_SetIF(AppPlci_t *aplci, u_int prim, void *arg)
{
int ret;
#ifdef FIXME
if (aplci->Bprotocol.B3 == 0) // transparent
ret = mISDN_SetIF(&aplci->link->inst, arg, prim, NULL, PL_l3l4, aplci);
else
ret = mISDN_SetIF(&aplci->link->inst, arg, prim, NULL, PL_l3l4mux, aplci);
if (ret)
return(ret);
#endif
if (!test_and_set_bit(PLCI_STATE_SENDDELAYED, &aplci->plci->state)) {
test_and_set_bit(PLCI_STATE_STACKREADY, &aplci->plci->state);
SendingDelayedMsg(aplci);

View File

@ -45,11 +45,11 @@ send_arcofi(dchannel_t *dch) {
}
isac->mocr &= 0x0f;
isac->mocr |= 0xa0;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
val = dch->read_reg(dch->inst.data, ISAC_MOSR);
dch->write_reg(dch->inst.data, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
val = dch->read_reg(dch->inst.privat, ISAC_MOSR);
dch->write_reg(dch->inst.privat, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
isac->mocr |= 0x10;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
}
int

View File

@ -19,14 +19,9 @@ bchannel_bh(bchannel_t *bch)
u_int pr;
int ret;
mISDN_head_t *hh;
mISDNif_t *hif;
if (!bch)
return;
if (!bch->inst.up.func) {
printk(KERN_WARNING "%s: without up.func\n", __FUNCTION__);
return;
}
#if 0
printk(KERN_DEBUG "%s: event %x\n", __FUNCTION__, bch->event);
if (bch->dev)
@ -42,27 +37,31 @@ bchannel_bh(bchannel_t *bch)
pr = DL_DATA | CONFIRM;
else
pr = PH_DATA | CONFIRM;
#ifdef FIXME
if ((bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
&& bch->dev)
hif = &bch->dev->rport.pif;
else
hif = &bch->inst.up;
if (if_newhead(hif, pr, hh->dinfo, skb))
#endif
if (mISDN_queueup_newhead(&bch->inst, 0, pr, hh->dinfo, skb))
dev_kfree_skb(skb);
}
}
if (test_and_clear_bit(B_RCVBUFREADY, &bch->event)) {
#ifdef FIXME
if ((bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
&& bch->dev)
hif = &bch->dev->rport.pif;
else
hif = &bch->inst.up;
#endif
while ((skb = skb_dequeue(&bch->rqueue))) {
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANS)
pr = DL_DATA | INDICATION;
else
pr = PH_DATA | INDICATION;
ret = if_newhead(hif, pr, MISDN_ID_ANY, skb);
ret = mISDN_queueup_newhead(&bch->inst, 0, pr, MISDN_ID_ANY, skb);
if (ret < 0) {
printk(KERN_WARNING "%s: deliver err %d\n",
__FUNCTION__, ret);

View File

@ -348,6 +348,7 @@ capi20_manager(void *data, u_int prim, void *arg) {
case MGR_NEWENTITY | CONFIRM:
ctrl->entity = (int)arg;
break;
#ifdef FIXME
case MGR_CONNECT | REQUEST:
return(mISDN_ConnectIF(inst, arg));
case MGR_SETIF | INDICATION:
@ -359,6 +360,7 @@ capi20_manager(void *data, u_int prim, void *arg) {
case MGR_DISCONNECT | REQUEST:
case MGR_DISCONNECT | INDICATION:
return(mISDN_DisConnectIF(inst, arg));
#endif
case MGR_RELEASE | INDICATION:
if (CAPI_DBG_INFO & debug)
printk(KERN_DEBUG "release_capi20 id %x\n", ctrl->inst.st->id);
@ -366,8 +368,8 @@ capi20_manager(void *data, u_int prim, void *arg) {
break;
case MGR_UNREGLAYER | REQUEST:
if (plink) {
capi_obj.ctrl(plink->inst.down.peer, MGR_DISCONNECT | REQUEST,
&plink->inst.down);
// capi_obj.ctrl(plink->inst.down.peer, MGR_DISCONNECT | REQUEST,
// &plink->inst.down);
capi_obj.ctrl(&plink->inst, MGR_UNREGLAYER | REQUEST, NULL);
}
break;

View File

@ -58,6 +58,7 @@ ControllerDestr(Controller_t *contr)
}
#endif
contr->ctrl = NULL;
#ifdef FIXME
if (inst->up.peer) {
inst->up.peer->obj->ctrl(inst->up.peer,
MGR_DISCONNECT | REQUEST, &inst->up);
@ -66,6 +67,7 @@ ControllerDestr(Controller_t *contr)
inst->down.peer->obj->ctrl(inst->down.peer,
MGR_DISCONNECT | REQUEST, &inst->down);
}
#endif
list_for_each_safe(item, next, &contr->linklist) {
PLInst_t *plink = list_entry(item, PLInst_t, list);
list_del(&plink->list);
@ -469,17 +471,15 @@ SSProcess_t
}
int
ControllerL3L4(mISDNif_t *hif, struct sk_buff *skb)
ControllerL3L4(mISDNinstance_t *inst, struct sk_buff *skb)
{
Controller_t *contr;
Plci_t *plci;
int ret = -EINVAL;
mISDN_head_t *hh;
if (!hif || !skb)
return(ret);
hh = mISDN_HEAD_P(skb);
contr = hif->fdata;
contr = inst->privat;
contrDebug(contr, CAPI_DBG_CONTR_INFO, "%s: prim(%x) id(%x)",
__FUNCTION__, hh->prim, hh->dinfo);
if (hh->prim == (CC_NEW_CR | INDICATION)) {
@ -503,7 +503,7 @@ ControllerL3L4(mISDNif_t *hif, struct sk_buff *skb)
int
ControllerL4L3(Controller_t *contr, u_int prim, int dinfo, struct sk_buff *skb)
{
return(if_newhead(&contr->inst.down, prim, dinfo, skb));
return(mISDN_queuedown_newhead(&contr->inst, 0, prim, dinfo, skb));
}
void
@ -598,7 +598,7 @@ ControllerConstr(Controller_t **contr_p, mISDNstack_t *st, mISDN_pid_t *pid, mIS
plink->inst.st = cst;
mISDN_init_instance(&plink->inst, ocapi, plink);
plink->inst.pid.layermask |= ISDN_LAYER(4);
plink->inst.down.stat = IF_NOACTIV;
// plink->inst.down.stat = IF_NOACTIV;
list_add_tail(&plink->list, &contr->linklist);
}
list_add_tail(&contr->list, &ocapi->ilist);
@ -636,7 +636,7 @@ ControllerConstr(Controller_t **contr_p, mISDNstack_t *st, mISDN_pid_t *pid, mIS
contr->addr = contr->ctrl->cnr;
plciInit(contr);
ocapi->ctrl(st, MGR_REGLAYER | INDICATION, &contr->inst);
contr->inst.up.stat = IF_DOWN;
// contr->inst.up.stat = IF_DOWN;
*contr_p = contr;
} else {
ControllerDestr(contr);

View File

@ -118,6 +118,7 @@ mISDNd(void *data)
err--; /* to free skb */
}
break;
#ifdef FIXME
case MGR_QUEUEIF:
err = hhe->func.iff(hhe->data[0], skb);
if (err) {
@ -125,6 +126,7 @@ mISDNd(void *data)
hhe->addr, hhe->prim, err);
}
break;
#endif
default:
int_error();
printk(KERN_WARNING "mISDNd: addr(%x) prim(%x) unknown\n",
@ -221,19 +223,22 @@ find_object_module(int protocol) {
static void
remove_object(mISDNobject_t *obj) {
mISDNstack_t *st, *nst;
mISDNlayer_t *layer, *nl;
mISDNinstance_t *inst;
mISDNstack_t *st, *nst;
// mISDNlayer_t *layer, *nl;
mISDNinstance_t *inst;
int i;
list_for_each_entry_safe(st, nst, &mISDN_stacklist, list) {
list_for_each_entry_safe(layer, nl, &st->layerlist, list) {
inst = layer->inst;
for (i = 0; i < MAX_LAYER_NR; i++) {
// list_for_each_entry_safe(layer, nl, &st->layerlist, list) {
inst = st->i_array[i];
if (inst && inst->obj == obj)
inst->obj->own_ctrl(st, MGR_RELEASE | INDICATION, inst);
}
}
}
#ifdef FIXME
static int
dummy_if(mISDNif_t *hif, struct sk_buff *skb)
{
@ -251,6 +256,7 @@ dummy_if(mISDNif_t *hif, struct sk_buff *skb)
dev_kfree_skb_any(skb);
return(0);
}
#endif
mISDNinstance_t *
get_next_instance(mISDNstack_t *st, mISDN_pid_t *pid)
@ -335,6 +341,7 @@ sel_channel(mISDNstack_t *st, channel_info_t *ci)
return(err);
}
#ifdef FIXME
static int
disconnect_if(mISDNinstance_t *inst, u_int prim, mISDNif_t *hif) {
int err = 0;
@ -371,6 +378,7 @@ add_if(mISDNinstance_t *inst, u_int prim, mISDNif_t *hif) {
inst->obj->own_ctrl(inst, prim, hif);
return(0);
}
#endif
static char tmpbuf[4096];
static int
@ -535,15 +543,19 @@ static int central_manager(void *data, u_int prim, void *arg) {
return(-EINVAL);
case MGR_UNREGLAYER | REQUEST:
return(unregister_instance(data));
#ifdef FIXME
case MGR_DISCONNECT | REQUEST:
case MGR_DISCONNECT | INDICATION:
return(disconnect_if(data, prim, arg));
#endif
case MGR_GETDEVICE | REQUEST:
return(get_hdevice(data, arg));
case MGR_DELDEVICE | REQUEST:
return(free_device(data));
#ifdef FIXME
case MGR_QUEUEIF | REQUEST:
return(mgr_queue(data, MGR_QUEUEIF, arg));
#endif
}
if (!data)
return(-EINVAL);
@ -559,24 +571,28 @@ static int central_manager(void *data, u_int prim, void *arg) {
return(release_stack(st));
case MGR_SELCHANNEL | REQUEST:
return(sel_channel(st, arg));
#ifdef FIXME
case MGR_ADDIF | REQUEST:
return(add_if(data, prim, arg));
#endif
case MGR_CTRLREADY | INDICATION:
return(queue_ctrl_ready(st, arg));
case MGR_ADDSTPARA | REQUEST:
case MGR_CLRSTPARA | REQUEST:
return(change_stack_para(st, prim, arg));
#ifdef FIXME
case MGR_CONNECT | REQUEST:
return(mISDN_ConnectIF(data, arg));
#endif
case MGR_EVALSTACK | REQUEST:
return(evaluate_stack_pids(data, arg));
case MGR_GLOBALOPT | REQUEST:
case MGR_LOADFIRM | REQUEST:
if (st->mgr && st->mgr->obj && st->mgr->obj->own_ctrl)
return(st->mgr->obj->own_ctrl(st->mgr, prim, arg));
break;
break;
case MGR_DEBUGDATA | REQUEST:
return(debugout(data, arg));
return(debugout(data, arg));
default:
if (debug)
printk(KERN_WARNING "manager prim %x not handled\n", prim);

View File

@ -50,7 +50,7 @@ extern int copy_pid(mISDN_pid_t *, mISDN_pid_t *, u_char *);
extern int set_stack(mISDNstack_t *, mISDN_pid_t *);
extern int clear_stack(mISDNstack_t *);
extern int evaluate_stack_pids(mISDNstack_t *, mISDN_pid_t *);
extern mISDNlayer_t *getlayer4lay(mISDNstack_t *, int);
//extern mISDNlayer_t *getlayer4lay(mISDNstack_t *, int);
extern mISDNinstance_t *get_instance(mISDNstack_t *, int, int);
/* from mISDN_core.c */

View File

@ -39,14 +39,14 @@ dchannel_bh(dchannel_t *dch)
hh = mISDN_HEAD_P(skb);
dch->next_skb = NULL;
skb_trim(skb, 0);
if (if_newhead(&dch->inst.up, PH_DATA_CNF, hh->dinfo, skb))
if (mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_CNF, hh->dinfo, skb))
dev_kfree_skb(skb);
}
}
if (test_and_clear_bit(D_RCVBUFREADY, &dch->event)) {
while ((skb = skb_dequeue(&dch->rqueue))) {
err = if_newhead(&dch->inst.up, PH_DATA_IND, MISDN_ID_ANY, skb);
err = mISDN_queueup_newhead(&dch->inst, 0, PH_DATA_IND, MISDN_ID_ANY, skb);
if (err < 0) {
printk(KERN_WARNING "%s: deliver err %d\n", __FUNCTION__, err);
dev_kfree_skb(skb);

View File

@ -350,7 +350,7 @@ isdn_audio_goertzel(dtmf_t *dtmf)
if (dtmf->debug & DEBUG_DTMF_TONE)
printk(KERN_DEBUG "DTMF: tone='%c'\n", what);
k = what | DTMF_TONE_VAL;
if_link(&dtmf->inst.up, PH_CONTROL | INDICATION,
mISDN_queue_data(&dtmf->inst, FLG_MSG_UP, PH_CONTROL | INDICATION,
0, sizeof(int), &k, 0);
}
dtmf->last = what;
@ -398,19 +398,14 @@ dtmf_reset(dtmf_t *dtmf)
}
static int
dtmf_from_up(mISDNif_t *hif, struct sk_buff *skb)
dtmf_from_up(mISDNinstance_t *inst, struct sk_buff *skb)
{
dtmf_t *dtmf;
mISDN_head_t *hh;
int *data;
int err = 0;
if (!hif || !hif->fdata || !skb)
return(-EINVAL);
dtmf = hif->fdata;
if (!dtmf->inst.down.func) {
return(-ENXIO);
}
dtmf = inst->privat;
hh = mISDN_HEAD_P(skb);
switch(hh->prim) {
case (PH_CONTROL | REQUEST):
@ -431,7 +426,7 @@ dtmf_from_up(mISDNif_t *hif, struct sk_buff *skb)
}
/* Fall trough in case of not handled function */
default:
return(dtmf->inst.down.func(&dtmf->inst.down, skb));
return(mISDN_queue_down(inst, 0, skb));
}
if (!err)
dev_kfree_skb(skb);
@ -439,17 +434,12 @@ dtmf_from_up(mISDNif_t *hif, struct sk_buff *skb)
}
static int
dtmf_from_down(mISDNif_t *hif, struct sk_buff *skb)
dtmf_from_down(mISDNinstance_t *inst, struct sk_buff *skb)
{
dtmf_t *dtmf;
mISDN_head_t *hh;
if (!hif || !hif->fdata || !skb)
return(-EINVAL);
dtmf = hif->fdata;
if (!dtmf->inst.up.func) {
return(-ENXIO);
}
dtmf = inst->privat;
hh = mISDN_HEAD_P(skb);
switch(hh->prim) {
case (PH_DATA | CONFIRM):
@ -474,21 +464,13 @@ dtmf_from_down(mISDNif_t *hif, struct sk_buff *skb)
hh->prim = DL_RELEASE | INDICATION;
break;
}
return(dtmf->inst.up.func(&dtmf->inst.up, skb));
return(mISDN_queue_up(inst, 0, skb));
}
static void
release_dtmf(dtmf_t *dtmf) {
mISDNinstance_t *inst = &dtmf->inst;
if (inst->up.peer) {
inst->up.peer->obj->ctrl(inst->up.peer,
MGR_DISCONNECT | REQUEST, &inst->up);
}
if (inst->down.peer) {
inst->down.peer->obj->ctrl(inst->down.peer,
MGR_DISCONNECT | REQUEST, &inst->down);
}
list_del(&dtmf->list);
dtmf_obj.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
kfree(dtmf);
@ -582,6 +564,7 @@ dtmf_manager(void *data, u_int prim, void *arg) {
case MGR_CLRSTPARA | INDICATION:
case MGR_CLONELAYER | REQUEST:
break;
#ifdef OBSOLATE
case MGR_CONNECT | REQUEST:
return(mISDN_ConnectIF(inst, arg));
case MGR_SETIF | REQUEST:
@ -590,6 +573,7 @@ dtmf_manager(void *data, u_int prim, void *arg) {
case MGR_DISCONNECT | REQUEST:
case MGR_DISCONNECT | INDICATION:
return(mISDN_DisConnectIF(inst, arg));
#endif
case MGR_UNREGLAYER | REQUEST:
case MGR_RELEASE | INDICATION:
if (debug & DEBUG_DTMF_MGR)

View File

@ -240,6 +240,7 @@ mISDN_get_up_layer(int layermask) {
return(uplayer);
}
#ifdef OBSOLATE
int
mISDN_SetIF(mISDNinstance_t *owner, mISDNif_t *hif, u_int prim, void *upfunc,
void *downfunc, void *data)
@ -339,6 +340,7 @@ mISDN_DisConnectIF(mISDNinstance_t *inst, mISDNif_t *hif) {
}
return(0);
}
#endif
void
mISDN_init_instance(mISDNinstance_t *inst, mISDNobject_t *obj, void *data)
@ -352,15 +354,7 @@ mISDN_init_instance(mISDNinstance_t *inst, mISDNobject_t *obj, void *data)
return;
}
inst->obj = obj;
inst->data = data;
inst->up.owner = inst;
inst->down.owner = inst;
inst->up.clone = NULL;
inst->up.predecessor = NULL;
inst->down.clone = NULL;
inst->down.predecessor = NULL;
obj->ctrl(NULL, MGR_DISCONNECT | REQUEST, &inst->down);
obj->ctrl(NULL, MGR_DISCONNECT | REQUEST, &inst->up);
inst->privat = data;
}
EXPORT_SYMBOL(mISDN_set_dchannel_pid);
@ -373,7 +367,7 @@ EXPORT_SYMBOL(mISDN_HasProtocol);
EXPORT_SYMBOL(mISDN_SetHandledPID);
EXPORT_SYMBOL(mISDN_RemoveUsedPID);
EXPORT_SYMBOL(mISDN_init_instance);
EXPORT_SYMBOL(mISDN_SetIF);
EXPORT_SYMBOL(mISDN_ConnectIF);
EXPORT_SYMBOL(mISDN_DisConnectIF);
// EXPORT_SYMBOL(mISDN_SetIF);
// EXPORT_SYMBOL(mISDN_ConnectIF);
// EXPORT_SYMBOL(mISDN_DisConnectIF);
EXPORT_SYMBOL(mISDN_bprotocol2pid);

View File

@ -176,30 +176,52 @@ mISDN_sethead(u_int prim, int dinfo, struct sk_buff *skb)
hh->dinfo = dinfo;
}
/* send the skb through this interface with new header values */
static inline int mISDN_send_message(void) {return 0;};
static inline int mISDN_send_data(void) {return 0;};
static inline int mISDN_sendup(void) {return 0;};
static inline int mISDN_sendup_newhead(void) {return 0;};
static inline int mISDN_senddown(void) {return 0;};
static inline int mISDN_senddown_newhead(void) {return 0;};
#define mISDN_queue_up(i, a, s) mISDN_queue_message(i, a | FLG_MSG_UP, s)
#define mISDN_queue_down(i, a, s) mISDN_queue_message(i, a | FLG_MSG_DOWN, s)
static inline int
if_newhead(mISDNif_t *i, u_int prim, int dinfo, struct sk_buff *skb)
mISDN_queueup_newhead(mISDNinstance_t *inst, u_int aflag, u_int prim, int dinfo, struct sk_buff *skb)
{
if (!i->func || !skb)
return(-ENXIO);
mISDN_sethead(prim, dinfo, skb);
return(i->func(i, skb));
mISDN_head_t *hh = mISDN_HEAD_P(skb);
hh->prim = prim;
hh->dinfo = dinfo;
return(mISDN_queue_up(inst, aflag, skb));
}
static inline int
mISDN_queuedown_newhead(mISDNinstance_t *inst, u_int aflag, u_int prim, int dinfo, struct sk_buff *skb)
{
mISDN_head_t *hh = mISDN_HEAD_P(skb);
hh->prim = prim;
hh->dinfo = dinfo;
return(mISDN_queue_down(inst, aflag, skb));
}
/* allocate a mISDN message SKB with enough headroom and set the header fields
* the MEMDEBUG version is for debugging memory leaks in the mISDN stack
*/
#ifdef MISDN_MEMDEBUG
#define create_link_skb(p, d, l, a, r) __mid_create_link_skb(p, d, l, a, r, __FILE__, __LINE__)
#define create_link_skb(p, d, l, dp, r) __mid_create_link_skb(p, d, l, dp, r, __FILE__, __LINE__)
static inline struct sk_buff *
__mid_create_link_skb(u_int prim, int dinfo, int len, void *arg, int reserve, char *fn, int line)
__mid_create_link_skb(u_int prim, int dinfo, int len, void *dp, int reserve, char *fn, int line)
{
struct sk_buff *skb;
if (!(skb = __mid_alloc_skb(len + reserve, GFP_ATOMIC, fn, line))) {
#else
static inline struct sk_buff *
create_link_skb(u_int prim, int dinfo, int len, void *arg, int reserve)
create_link_skb(u_int prim, int dinfo, int len, void *dp, int reserve)
{
struct sk_buff *skb;
@ -211,7 +233,7 @@ create_link_skb(u_int prim, int dinfo, int len, void *arg, int reserve)
} else
skb_reserve(skb, reserve);
if (len)
memcpy(skb_put(skb, len), arg, len);
memcpy(skb_put(skb, len), dp, len);
mISDN_sethead(prim, dinfo, skb);
return(skb);
}
@ -221,28 +243,25 @@ create_link_skb(u_int prim, int dinfo, int len, void *arg, int reserve)
* the MEMDEBUG version is for debugging memory leaks in the mISDN stack
*/
#ifdef MISDN_MEMDEBUG
#define if_link(i, p, d, l, a, r) __mid_if_link(i, p, d, l, a, r, __FILE__, __LINE__)
#define mISDN_queue_data(i, a, p, d, l, dp, r) __mid_queue_data(i, a, p, d, l, dp, r, __FILE__, __LINE__)
static inline int
__mid_if_link(mISDNif_t *i, u_int prim, int dinfo, int len, void *arg, int reserve, char *fn, int line)
__mid_queue_data(mISDNinstance_t *inst, u_int aflag, u_int prim, int dinfo, int len, void *dp, int reserve, char *fn, int line)
{
struct sk_buff *skb;
int err;
if (!(skb = __mid_create_link_skb(prim, dinfo, len, arg, reserve, fn, line)))
if (!(skb = __mid_create_link_skb(prim, dinfo, len, dp, reserve, fn, line)))
#else
static inline int
if_link(mISDNif_t *i, u_int prim, int dinfo, int len, void *arg, int reserve)
mISDN_queue_data(mISDNinstance_t *inst, u_int aflag, u_int prim, int dinfo, int len, void *dp, int reserve)
{
struct sk_buff *skb;
int err;
if (!(skb = create_link_skb(prim, dinfo, len, arg, reserve)))
if (!(skb = create_link_skb(prim, dinfo, len, dp, reserve)))
#endif
return(-ENOMEM);
if (!i)
err = -ENXIO;
else
err = i->func(i, skb);
err = mISDN_queue_message(inst, aflag, skb);
if (err)
kfree_skb(skb);
return(err);

View File

@ -597,7 +597,7 @@ hfcpci_empty_fifo_trans(bchannel_t *bch, bzfifo_type * bz, u_char * bdata)
void
main_rec_hfcpci(bchannel_t *bch)
{
hfc_pci_t *hc = bch->inst.data;
hfc_pci_t *hc = bch->hw;
int rcnt, real_fifo;
int receive, count = 5;
struct sk_buff *skb;
@ -740,7 +740,7 @@ hfcpci_fill_dfifo(hfc_pci_t *hc)
static void
hfcpci_fill_fifo(bchannel_t *bch)
{
hfc_pci_t *hc = bch->inst.data;
hfc_pci_t *hc = bch->hw;
int maxlen, fcnt;
int count, new_z1;
bzfifo_type *bz;
@ -1278,51 +1278,49 @@ hfcpci_dbusy_timer(hfc_pci_t *hc)
/* Layer 1 D-channel hardware access */
/*************************************/
static int
HFCD_l1hw(mISDNif_t *hif, struct sk_buff *skb)
HFCD_l1hw(mISDNinstance_t *inst, struct sk_buff *skb)
{
dchannel_t *dch;
hfc_pci_t *hc;
int ret = -EINVAL;
mISDN_head_t *hh;
if (!hif || !skb)
return(ret);
hh = mISDN_HEAD_P(skb);
dch = hif->fdata;
hc = dch->inst.data;
dch = container_of(inst, dchannel_t, inst);
hc = inst->privat;
ret = 0;
if (hh->prim == PH_DATA_REQ) {
if (dch->next_skb) {
printk(KERN_WARNING "%s: next_skb exist ERROR\n", __FUNCTION__);
return(-EBUSY);
}
dch->inst.lock(dch->inst.data, 0);
dch->inst.lock(hc, 0);
if (test_and_set_bit(FLG_TX_BUSY, &dch->DFlags)) {
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
dch->next_skb = skb;
dch->inst.unlock(dch->inst.data);
dch->inst.unlock(hc);
return(0);
} else {
dch->tx_len = skb->len;
memcpy(dch->tx_buf, skb->data, dch->tx_len);
dch->tx_idx = 0;
hfcpci_fill_dfifo(dch->inst.data);
dch->inst.unlock(dch->inst.data);
hfcpci_fill_dfifo(hc);
dch->inst.unlock(hc);
skb_trim(skb, 0);
return(if_newhead(&dch->inst.up, PH_DATA_CNF,
return(mISDN_queueup_newhead(inst, 0, PH_DATA_CNF,
hh->dinfo, skb));
}
} else if (hh->prim == (PH_SIGNAL | REQUEST)) {
dch->inst.lock(dch->inst.data, 0);
dch->inst.lock(hc, 0);
if ((hh->dinfo == INFO3_P8) || (hh->dinfo == INFO3_P10)) {
if (test_bit(HFC_CFG_MASTER, &hc->cfg))
hc->hw.mst_m |= HFCPCI_MASTER;
Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
} else
ret = -EINVAL;
dch->inst.unlock(dch->inst.data);
dch->inst.unlock(hc);
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
dch->inst.lock(dch->inst.data, 0);
dch->inst.lock(hc, 0);
if (hh->dinfo == HW_RESET) {
Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | 3); /* HFC ST 3 */
udelay(6);
@ -1385,10 +1383,10 @@ HFCD_l1hw(mISDNif_t *hif, struct sk_buff *skb)
__FUNCTION__, hh->dinfo);
ret = -EINVAL;
}
dch->inst.unlock(dch->inst.data);
dch->inst.unlock(hc);
} else if (hh->prim == (PH_ACTIVATE | REQUEST)) {
if (hc->hw.nt_mode) {
dch->inst.lock(dch->inst.data, 0);
dch->inst.lock(hc, 0);
Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | 0); /* G0 */
udelay(6);
Write_hfc(hc, HFCPCI_STATES, HFCPCI_LOAD_STATE | 1); /* G1 */
@ -1398,7 +1396,7 @@ HFCD_l1hw(mISDNif_t *hif, struct sk_buff *skb)
Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
udelay(6);
Write_hfc(hc, HFCPCI_STATES, HFCPCI_ACTIVATE | HFCPCI_DO_ACTION | 1);
dch->inst.unlock(dch->inst.data);
dch->inst.unlock(hc);
} else {
if (dch->debug & L1_DEB_WARN)
mISDN_debugprint(&dch->inst, "%s: PH_ACTIVATE none NT mode",
@ -1407,7 +1405,7 @@ HFCD_l1hw(mISDNif_t *hif, struct sk_buff *skb)
}
} else if (hh->prim == (PH_DEACTIVATE | REQUEST)) {
if (hc->hw.nt_mode) {
dch->inst.lock(dch->inst.data, 0);
dch->inst.lock(hc, 0);
hc->hw.mst_m &= ~HFCPCI_MASTER;
Write_hfc(hc, HFCPCI_MST_MODE, hc->hw.mst_m);
discard_queue(&dch->rqueue);
@ -1421,7 +1419,7 @@ HFCD_l1hw(mISDNif_t *hif, struct sk_buff *skb)
del_timer(&dch->dbusytimer);
if (test_and_clear_bit(FLG_L1_DBUSY, &dch->DFlags))
dchannel_sched_event(&hc->dch, D_CLEARBUSY);
dch->inst.unlock(dch->inst.data);
dch->inst.unlock(hc);
} else {
if (dch->debug & L1_DEB_WARN)
mISDN_debugprint(&dch->inst, "%s: PH_DEACTIVATE none NT mode",
@ -1445,7 +1443,7 @@ HFCD_l1hw(mISDNif_t *hif, struct sk_buff *skb)
static int
mode_hfcpci(bchannel_t *bch, int bc, int protocol)
{
hfc_pci_t *hc = bch->inst.data;
hfc_pci_t *hc = bch->hw;
int fifo2;
u_char rx_slot = 0, tx_slot = 0, pcm_mode;
@ -1643,7 +1641,7 @@ mode_hfcpci(bchannel_t *bch, int bc, int protocol)
static int
set_hfcpci_rxtest(bchannel_t *bch, int protocol, struct sk_buff *skb)
{
hfc_pci_t *hc = bch->inst.data;
hfc_pci_t *hc = bch->hw;
int *chan = (int *)skb->data;
if (skb->len <4) {
@ -1720,16 +1718,14 @@ set_hfcpci_rxtest(bchannel_t *bch, int protocol, struct sk_buff *skb)
/* Layer2 -> Layer 1 Transfer */
/******************************/
static int
hfcpci_l2l1(mISDNif_t *hif, struct sk_buff *skb)
hfcpci_l2l1(mISDNinstance_t *inst, struct sk_buff *skb)
{
bchannel_t *bch;
bchannel_t *bch = container_of(inst, bchannel_t, inst);
hfc_pci_t *hc = inst->privat;
int ret = -EINVAL;
mISDN_head_t *hh;
if (!hif || !skb)
return(ret);
hh = mISDN_HEAD_P(skb);
bch = hif->fdata;
if ((hh->prim == PH_DATA_REQ) ||
(hh->prim == (DL_DATA | REQUEST))) {
#warning TODO: hier muss abgefragt werden, ob skb->len <= 0 ist, und ggf. ein -EINVAL zurückliefern, sonst wird zwar einmal confirmed, aber es regt sich nichts mehr. dies bitte auch für den d-kanal überdenken, sowie für alle andere kartentreiber.
@ -1738,25 +1734,27 @@ hfcpci_l2l1(mISDNif_t *hif, struct sk_buff *skb)
__FUNCTION__);
return(-EBUSY);
}
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(hc, 0);
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
bch->next_skb = skb;
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(hc);
return(0);
} else {
bch->tx_len = skb->len;
memcpy(bch->tx_buf, skb->data, bch->tx_len);
bch->tx_idx = 0;
hfcpci_fill_fifo(bch);
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(hc);
#ifdef FIXME
if ((bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
&& bch->dev)
hif = &bch->dev->rport.pif;
else
hif = &bch->inst.up;
#endif
skb_trim(skb, 0);
return(if_newhead(hif, hh->prim | CONFIRM,
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM,
hh->dinfo, skb));
}
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
@ -1764,21 +1762,23 @@ hfcpci_l2l1(mISDNif_t *hif, struct sk_buff *skb)
if (test_and_set_bit(BC_FLG_ACTIV, &bch->Flag))
ret = 0;
else {
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(hc, 0);
ret = mode_hfcpci(bch, bch->channel,
bch->inst.pid.protocol[1]);
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(hc);
}
#ifdef FIXME
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
if (bch->dev)
if_link(&bch->dev->rport.pif,
hh->prim | CONFIRM, 0, 0, NULL, 0);
#endif
skb_trim(skb, 0);
return(if_newhead(&bch->inst.up, hh->prim | CONFIRM, ret, 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))) {
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(hc, 0);
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
dev_kfree_skb(bch->next_skb);
bch->next_skb = NULL;
@ -1786,19 +1786,21 @@ hfcpci_l2l1(mISDNif_t *hif, struct sk_buff *skb)
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
mode_hfcpci(bch, bch->channel, ISDN_PID_NONE);
test_and_clear_bit(BC_FLG_ACTIV, &bch->Flag);
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(hc);
skb_trim(skb, 0);
if (hh->prim != (MGR_DISCONNECT | REQUEST)) {
#ifdef FIXME
if (bch->inst.pid.protocol[2] == ISDN_PID_L2_B_RAWDEV)
if (bch->dev)
if_link(&bch->dev->rport.pif,
hh->prim | CONFIRM, 0, 0, NULL, 0);
if (!if_newhead(&bch->inst.up, hh->prim | CONFIRM, 0, skb))
#endif
if (!mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, 0, skb))
return(0);
}
ret = 0;
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(hc, 0);
if (hh->dinfo == HW_TESTRX_RAW) {
ret = set_hfcpci_rxtest(bch, ISDN_PID_L1_B_64TRANS, skb);
} else if (hh->dinfo == HW_TESTRX_HDLC) {
@ -1808,10 +1810,10 @@ hfcpci_l2l1(mISDNif_t *hif, struct sk_buff *skb)
ret = 0;
} else
ret = -EINVAL;
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(hc);
if (!ret) {
skb_trim(skb, 0);
if (!if_newhead(&bch->inst.up, hh->prim | CONFIRM, hh->dinfo, skb))
if (!mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, hh->dinfo, skb))
return(0);
}
} else {
@ -1831,10 +1833,9 @@ hfcpci_l2l1(mISDNif_t *hif, struct sk_buff *skb)
static void
HW_hfcD_bh(dchannel_t *dch)
{
hfc_pci_t *hc = dch->inst.data;
hfc_pci_t *hc = dch->inst.privat;
u_int prim = PH_SIGNAL | INDICATION;
u_int para = 0;
mISDNif_t *upif = &dch->inst.up;
if (test_and_clear_bit(D_L1STATECHANGE, &dch->event)) {
if (!hc->hw.nt_mode) {
@ -1867,7 +1868,7 @@ HW_hfcD_bh(dchannel_t *dch)
if (dch->debug)
printk(KERN_DEBUG "%s: NT newstate %x\n",
__FUNCTION__, dch->ph_state);
dch->inst.lock(dch->inst.data, 0);
dch->inst.lock(hc, 0);
switch (dch->ph_state) {
case (2):
if (hc->hw.nt_timer < 0) {
@ -1891,8 +1892,8 @@ HW_hfcD_bh(dchannel_t *dch)
hc->hw.nt_timer = NT_T1_COUNT;
Write_hfc(hc, HFCPCI_STATES, 2 | HFCPCI_NT_G2_G3); /* allow G2 -> G3 transition */
}
upif = NULL;
break;
dch->inst.unlock(hc);
return;
case (1):
prim = PH_DEACTIVATE | INDICATION;
para = 0;
@ -1904,8 +1905,8 @@ HW_hfcD_bh(dchannel_t *dch)
hc->hw.nt_timer = 0;
hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
upif = NULL;
break;
dch->inst.unlock(hc);
return;
case (3):
prim = PH_ACTIVATE | INDICATION;
para = 0;
@ -1916,12 +1917,9 @@ HW_hfcD_bh(dchannel_t *dch)
default:
break;
}
dch->inst.unlock(dch->inst.data);
}
while(upif) {
if_link(upif, prim, para, 0, NULL, 0);
upif = upif->clone;
dch->inst.unlock(hc);
}
mISDN_queue_data(&dch->inst, FLG_MSG_UP, prim, para, 0, NULL, 0);
}
}
@ -2062,11 +2060,12 @@ SelFreeBChannel(hfc_pci_t *hc, channel_info_t *ci)
} else
head = &bst->childlist;
list_for_each_entry(bst, head, list) {
if(!bst->mgr) {
if (!bst->mgr) {
int_errtxt("no mgr st(%p)", bst);
return(-EINVAL);
}
hfc = bst->mgr->data;
bch = container_of(bst->mgr, bchannel_t, inst);
hfc = bst->mgr->privat;
if (!hfc) {
int_errtxt("no mgr->data st(%p)", bst);
return(-EINVAL);
@ -2248,7 +2247,7 @@ release_card(hfc_pci_t *hc) {
mISDN_free_bch(&hc->bch[1]);
mISDN_free_bch(&hc->bch[0]);
mISDN_free_dch(&hc->dch);
HFC_obj.ctrl(hc->dch.inst.up.peer, MGR_DISCONNECT | REQUEST, &hc->dch.inst.up);
// HFC_obj.ctrl(hc->dch.inst.up.peer, MGR_DISCONNECT | REQUEST, &hc->dch.inst.up);
HFC_obj.ctrl(&hc->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
list_del(&hc->list);
unlock_dev(hc);
@ -2298,21 +2297,18 @@ HFC_manager(void *data, u_int prim, void *arg) {
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 (HFCD_l1hw(&inst->down, skb))
if (HFCD_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))) {
if (hfcpci_l2l1(&inst->down, skb))
if (hfcpci_l2l1(inst, skb))
dev_kfree_skb(skb);
}
}
HFC_obj.ctrl(inst->up.peer, MGR_DISCONNECT | REQUEST, &inst->up);
HFC_obj.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
break;
case MGR_CLRSTPARA | INDICATION:
@ -2330,6 +2326,7 @@ HFC_manager(void *data, u_int prim, void *arg) {
HFC_obj.refcnt--;
}
break;
#ifdef FIXME
case MGR_CONNECT | REQUEST:
return(mISDN_ConnectIF(inst, arg));
case MGR_SETIF | REQUEST:
@ -2343,6 +2340,7 @@ HFC_manager(void *data, u_int prim, void *arg) {
case MGR_DISCONNECT | REQUEST:
case MGR_DISCONNECT | INDICATION:
return(mISDN_DisConnectIF(inst, arg));
#endif
case MGR_SELCHANNEL | REQUEST:
if (channel != 2) {
printk(KERN_WARNING "%s: selchannel not dinst\n",
@ -2352,17 +2350,15 @@ HFC_manager(void *data, u_int prim, void *arg) {
return(SelFreeBChannel(card, arg));
case MGR_SETSTACK | CONFIRM:
if ((channel!=2) && (inst->pid.global == 2)) {
inst->down.fdata = &card->bch[channel];
if ((skb = create_link_skb(PH_ACTIVATE | REQUEST,
0, 0, NULL, 0))) {
if (hfcpci_l2l1(&inst->down, skb))
if ((skb = create_link_skb(PH_ACTIVATE | REQUEST, 0, 0, NULL, 0))) {
if (hfcpci_l2l1(inst, skb))
dev_kfree_skb(skb);
}
if (inst->pid.protocol[2] == ISDN_PID_L2_B_TRANS)
if_link(&inst->up, DL_ESTABLISH | INDICATION,
mISDN_queue_data(inst, FLG_MSG_UP, DL_ESTABLISH | INDICATION,
0, 0, NULL, 0);
else
if_link(&inst->up, PH_ACTIVATE | INDICATION,
mISDN_queue_data(inst, FLG_MSG_UP, PH_ACTIVATE | INDICATION,
0, 0, NULL, 0);
}
break;
@ -2426,12 +2422,14 @@ static int __init HFC_init(void)
sprintf(card->bch[i].inst.name, "%s B%d",
card->dch.inst.name, i+1);
mISDN_init_bch(&card->bch[i]);
#ifdef FIXME
if (card->bch[i].dev) {
card->bch[i].dev->wport.pif.func =
hfcpci_l2l1;
card->bch[i].dev->wport.pif.fdata =
&card->bch[i];
}
#endif
}
if (protocol[HFC_cnt] == 0x100) {
if (card->list.prev == &HFC_obj.ilist)

View File

@ -42,9 +42,9 @@ ph_command(dchannel_t *dch, unsigned int command)
if (dch->debug & L1_DEB_ISAC)
mISDN_debugprint(&dch->inst, "ph_command %x", command);
if (dch->type & ISAC_TYPE_ISACSX)
dch->write_reg(dch->inst.data, ISACSX_CIX0, (command << 4) | 0xE);
dch->write_reg(dch->inst.privat, ISACSX_CIX0, (command << 4) | 0xE);
else
dch->write_reg(dch->inst.data, ISAC_CIX0, (command << 2) | 3);
dch->write_reg(dch->inst.privat, ISAC_CIX0, (command << 2) | 3);
}
static void
@ -52,14 +52,13 @@ isac_new_ph(dchannel_t *dch)
{
u_int prim = PH_SIGNAL | INDICATION;
u_int para = 0;
mISDNif_t *upif = &dch->inst.up;
switch (dch->ph_state) {
case (ISAC_IND_RS):
case (ISAC_IND_EI):
dch->inst.lock(dch->inst.data,0);
dch->inst.lock(dch->inst.privat,0);
ph_command(dch, ISAC_CMD_DUI);
dch->inst.unlock(dch->inst.data);
dch->inst.unlock(dch->inst.privat);
prim = PH_CONTROL | INDICATION;
para = HW_RESET;
break;
@ -90,10 +89,7 @@ isac_new_ph(dchannel_t *dch)
default:
return;
}
while(upif) {
if_link(upif, prim, para, 0, NULL, 0);
upif = upif->clone;
}
mISDN_queue_data(&dch->inst, FLG_MSG_UP, prim, para, 0, NULL, 0);
}
static void
@ -135,7 +131,7 @@ isac_empty_fifo(dchannel_t *dch, int count)
if (!dch->rx_skb) {
if (!(dch->rx_skb = alloc_stack_skb(MAX_DFRAME_LEN_L1, dch->up_headerlen))) {
printk(KERN_WARNING "mISDN: D receive out of memory\n");
dch->write_reg(dch->inst.data, ISAC_CMDR, 0x80);
dch->write_reg(dch->inst.privat, ISAC_CMDR, 0x80);
return;
}
}
@ -143,12 +139,12 @@ isac_empty_fifo(dchannel_t *dch, int count)
if (dch->debug & L1_DEB_WARN)
mISDN_debugprint(&dch->inst, "isac_empty_fifo overrun %d",
dch->rx_skb->len + count);
dch->write_reg(dch->inst.data, ISAC_CMDR, 0x80);
dch->write_reg(dch->inst.privat, ISAC_CMDR, 0x80);
return;
}
ptr = skb_put(dch->rx_skb, count);
dch->read_fifo(dch->inst.data, ptr, count);
dch->write_reg(dch->inst.data, ISAC_CMDR, 0x80);
dch->read_fifo(dch->inst.privat, ptr, count);
dch->write_reg(dch->inst.privat, ISAC_CMDR, 0x80);
if (dch->debug & L1_DEB_ISAC_FIFO) {
char *t = dch->dlog;
@ -178,8 +174,8 @@ isac_fill_fifo(dchannel_t *dch)
}
ptr = dch->tx_buf + dch->tx_idx;
dch->tx_idx += count;
dch->write_fifo(dch->inst.data, ptr, count);
dch->write_reg(dch->inst.data, ISAC_CMDR, more ? 0x8 : 0xa);
dch->write_fifo(dch->inst.privat, ptr, count);
dch->write_reg(dch->inst.privat, ISAC_CMDR, more ? 0x8 : 0xa);
if (test_and_set_bit(FLG_DBUSY_TIMER, &dch->DFlags)) {
mISDN_debugprint(&dch->inst, "isac_fill_fifo dbusytimer running");
del_timer(&dch->dbusytimer);
@ -202,7 +198,7 @@ isac_rme_irq(dchannel_t *dch)
u_char val;
u_int count;
val = dch->read_reg(dch->inst.data, ISAC_RSTA);
val = dch->read_reg(dch->inst.privat, ISAC_RSTA);
if ((val & 0x70) != 0x20) {
if (val & 0x40) {
if (dch->debug & L1_DEB_WARN)
@ -218,11 +214,11 @@ isac_rme_irq(dchannel_t *dch)
dch->err_crc++;
#endif
}
dch->write_reg(dch->inst.data, ISAC_CMDR, 0x80);
dch->write_reg(dch->inst.privat, ISAC_CMDR, 0x80);
if (dch->rx_skb)
dev_kfree_skb(dch->rx_skb);
} else {
count = dch->read_reg(dch->inst.data, ISAC_RBCL) & 0x1f;
count = dch->read_reg(dch->inst.privat, ISAC_RBCL) & 0x1f;
if (count == 0)
count = 32;
isac_empty_fifo(dch, count);
@ -297,7 +293,7 @@ isac_mos_irq(dchannel_t *dch)
u_char val;
isac_chip_t *isac = dch->hw;
val = dch->read_reg(dch->inst.data, ISAC_MOSR);
val = dch->read_reg(dch->inst.privat, ISAC_MOSR);
if (dch->debug & L1_DEB_MONITOR)
mISDN_debugprint(&dch->inst, "ISAC MOSR %02x", val);
#if ARCOFI_USE
@ -308,7 +304,7 @@ isac_mos_irq(dchannel_t *dch)
mISDN_debugprint(&dch->inst, "ISAC MON RX out of memory!");
isac->mocr &= 0xf0;
isac->mocr |= 0x0a;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
goto afterMONR0;
} else
isac->mon_rxp = 0;
@ -316,18 +312,18 @@ isac_mos_irq(dchannel_t *dch)
if (isac->mon_rxp >= MAX_MON_FRAME) {
isac->mocr &= 0xf0;
isac->mocr |= 0x0a;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
isac->mon_rxp = 0;
if (dch->debug & L1_DEB_WARN)
mISDN_debugprint(&dch->inst, "ISAC MON RX overflow!");
goto afterMONR0;
}
isac->mon_rx[isac->mon_rxp++] = dch->read_reg(dch->inst.data, ISAC_MOR0);
isac->mon_rx[isac->mon_rxp++] = dch->read_reg(dch->inst.privat, ISAC_MOR0);
if (dch->debug & L1_DEB_MONITOR)
mISDN_debugprint(&dch->inst, "ISAC MOR0 %02x", isac->mon_rx[isac->mon_rxp -1]);
if (isac->mon_rxp == 1) {
isac->mocr |= 0x04;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
}
}
afterMONR0:
@ -338,7 +334,7 @@ afterMONR0:
mISDN_debugprint(&dch->inst, "ISAC MON RX out of memory!");
isac->mocr &= 0x0f;
isac->mocr |= 0xa0;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
goto afterMONR1;
} else
isac->mon_rxp = 0;
@ -346,40 +342,40 @@ afterMONR0:
if (isac->mon_rxp >= MAX_MON_FRAME) {
isac->mocr &= 0x0f;
isac->mocr |= 0xa0;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
isac->mon_rxp = 0;
if (dch->debug & L1_DEB_WARN)
mISDN_debugprint(&dch->inst, "ISAC MON RX overflow!");
goto afterMONR1;
}
isac->mon_rx[isac->mon_rxp++] = dch->read_reg(dch->inst.data, ISAC_MOR1);
isac->mon_rx[isac->mon_rxp++] = dch->read_reg(dch->inst.privat, ISAC_MOR1);
if (dch->debug & L1_DEB_MONITOR)
mISDN_debugprint(&dch->inst, "ISAC MOR1 %02x", isac->mon_rx[isac->mon_rxp -1]);
isac->mocr |= 0x40;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
}
afterMONR1:
if (val & 0x04) {
isac->mocr &= 0xf0;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
isac->mocr |= 0x0a;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
dchannel_sched_event(dch, D_RX_MON0);
}
if (val & 0x40) {
isac->mocr &= 0x0f;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
isac->mocr |= 0xa0;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
dchannel_sched_event(dch, D_RX_MON1);
}
if (val & 0x02) {
if ((!isac->mon_tx) || (isac->mon_txc &&
(isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) {
isac->mocr &= 0xf0;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
isac->mocr |= 0x0a;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc))
dchannel_sched_event(dch, D_TX_MON0);
goto AfterMOX0;
@ -388,7 +384,7 @@ afterMONR1:
dchannel_sched_event(dch, D_TX_MON0);
goto AfterMOX0;
}
dch->write_reg(dch->inst.data, ISAC_MOX0,
dch->write_reg(dch->inst.privat, ISAC_MOX0,
isac->mon_tx[isac->mon_txp++]);
if (dch->debug & L1_DEB_MONITOR)
mISDN_debugprint(&dch->inst, "ISAC %02x -> MOX0", isac->mon_tx[isac->mon_txp -1]);
@ -398,9 +394,9 @@ AfterMOX0:
if ((!isac->mon_tx) || (isac->mon_txc &&
(isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) {
isac->mocr &= 0x0f;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
isac->mocr |= 0xa0;
dch->write_reg(dch->inst.data, ISAC_MOCR, isac->mocr);
dch->write_reg(dch->inst.privat, ISAC_MOCR, isac->mocr);
if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc))
dchannel_sched_event(dch, D_TX_MON1);
goto AfterMOX1;
@ -409,7 +405,7 @@ AfterMOX0:
dchannel_sched_event(dch, D_TX_MON1);
goto AfterMOX1;
}
dch->write_reg(dch->inst.data, ISAC_MOX1,
dch->write_reg(dch->inst.privat, ISAC_MOX1,
isac->mon_tx[isac->mon_txp++]);
if (dch->debug & L1_DEB_MONITOR)
mISDN_debugprint(&dch->inst, "ISAC %02x -> MOX1", isac->mon_tx[isac->mon_txp -1]);
@ -423,7 +419,7 @@ static void
isac_cisq_irq(dchannel_t *dch) {
unsigned char val;
val = dch->read_reg(dch->inst.data, ISAC_CIR0);
val = dch->read_reg(dch->inst.privat, ISAC_CIR0);
if (dch->debug & L1_DEB_ISAC)
mISDN_debugprint(&dch->inst, "ISAC CIR0 %02X", val);
if (val & 2) {
@ -434,7 +430,7 @@ isac_cisq_irq(dchannel_t *dch) {
dchannel_sched_event(dch, D_L1STATECHANGE);
}
if (val & 1) {
val = dch->read_reg(dch->inst.data, ISAC_CIR1);
val = dch->read_reg(dch->inst.privat, ISAC_CIR1);
if (dch->debug & L1_DEB_ISAC)
mISDN_debugprint(&dch->inst, "ISAC CIR1 %02X", val );
}
@ -445,7 +441,7 @@ isacsx_cic_irq(dchannel_t *dch)
{
unsigned char val;
val = dch->read_reg(dch->inst.data, ISACSX_CIR0);
val = dch->read_reg(dch->inst.privat, ISACSX_CIR0);
if (dch->debug & L1_DEB_ISAC)
mISDN_debugprint(&dch->inst, "ISACSX CIR0 %02X", val);
if (val & ISACSX_CIR0_CIC0) {
@ -463,7 +459,7 @@ isacsx_rme_irq(dchannel_t *dch)
int count;
unsigned char val;
val = dch->read_reg(dch->inst.data, ISACSX_RSTAD);
val = dch->read_reg(dch->inst.privat, ISACSX_RSTAD);
if ((val & (ISACSX_RSTAD_VFR |
ISACSX_RSTAD_RDO |
ISACSX_RSTAD_CRC |
@ -477,11 +473,11 @@ isacsx_rme_irq(dchannel_t *dch)
else
dch->err_crc++;
#endif
dch->write_reg(dch->inst.data, ISACSX_CMDRD, ISACSX_CMDRD_RMC);
dch->write_reg(dch->inst.privat, ISACSX_CMDRD, ISACSX_CMDRD_RMC);
if (dch->rx_skb)
dev_kfree_skb(dch->rx_skb);
} else {
count = dch->read_reg(dch->inst.data, ISACSX_RBCLD) & 0x1f;
count = dch->read_reg(dch->inst.privat, ISACSX_RBCLD) & 0x1f;
if (count == 0)
count = 32;
isac_empty_fifo(dch, count);
@ -503,7 +499,7 @@ mISDN_isac_interrupt(dchannel_t *dch, u_char val)
if (val & ISACSX_ISTA_CIC)
isacsx_cic_irq(dch);
if (val & ISACSX_ISTA_ICD) {
val = dch->read_reg(dch->inst.data, ISACSX_ISTAD);
val = dch->read_reg(dch->inst.privat, ISACSX_ISTAD);
if (dch->debug & L1_DEB_ISAC)
mISDN_debugprint(&dch->inst, "ISTAD %02x", val);
if (val & ISACSX_ISTAD_XDU) {
@ -527,7 +523,7 @@ mISDN_isac_interrupt(dchannel_t *dch, u_char val)
if (val & ISACSX_ISTAD_RFO) {
if (dch->debug & L1_DEB_WARN)
mISDN_debugprint(&dch->inst, "ISAC RFO");
dch->write_reg(dch->inst.data, ISACSX_CMDRD, ISACSX_CMDRD_RMC);
dch->write_reg(dch->inst.privat, ISACSX_CMDRD, ISACSX_CMDRD_RMC);
}
if (val & ISACSX_ISTAD_RME)
isacsx_rme_irq(dch);
@ -550,7 +546,7 @@ mISDN_isac_interrupt(dchannel_t *dch, u_char val)
if (dch->debug & L1_DEB_WARN)
mISDN_debugprint(&dch->inst, "ISAC SIN interrupt");
if (val & 0x01) { /* EXI */
val = dch->read_reg(dch->inst.data, ISAC_EXIR);
val = dch->read_reg(dch->inst.privat, ISAC_EXIR);
if (dch->debug & L1_DEB_WARN)
mISDN_debugprint(&dch->inst, "ISAC EXIR %02x", val);
if (val & 0x80) /* XMR */
@ -570,48 +566,47 @@ mISDN_isac_interrupt(dchannel_t *dch, u_char val)
}
int
mISDN_ISAC_l1hw(mISDNif_t *hif, struct sk_buff *skb)
mISDN_ISAC_l1hw(mISDNinstance_t *inst, struct sk_buff *skb)
{
dchannel_t *dch;
int ret = -EINVAL;
mISDN_head_t *hh;
if (!hif || !skb)
return(ret);
hh = mISDN_HEAD_P(skb);
dch = hif->fdata;
dch = container_of(inst, dchannel_t, inst);
ret = 0;
if (hh->prim == PH_DATA_REQ) {
if (dch->next_skb) {
mISDN_debugprint(&dch->inst, " l2l1 next_skb exist this shouldn't happen");
return(-EBUSY);
}
dch->inst.lock(dch->inst.data,0);
dch->inst.lock(dch->inst.privat,0);
if (test_and_set_bit(FLG_TX_BUSY, &dch->DFlags)) {
test_and_set_bit(FLG_TX_NEXT, &dch->DFlags);
dch->next_skb = skb;
dch->inst.unlock(dch->inst.data);
dch->inst.unlock(dch->inst.privat);
return(0);
} else {
dch->tx_len = skb->len;
memcpy(dch->tx_buf, skb->data, dch->tx_len);
dch->tx_idx = 0;
isac_fill_fifo(dch);
dch->inst.unlock(dch->inst.data);
return(if_newhead(&dch->inst.up, PH_DATA_CNF,
dch->inst.unlock(dch->inst.privat);
skb_trim(skb, 0);
return(mISDN_queueup_newhead(inst, 0, PH_DATA_CNF,
hh->dinfo, skb));
}
} else if (hh->prim == (PH_SIGNAL | REQUEST)) {
dch->inst.lock(dch->inst.data,0);
dch->inst.lock(dch->inst.privat,0);
if (hh->dinfo == INFO3_P8)
ph_command(dch, ISAC_CMD_AR8);
else if (hh->dinfo == INFO3_P10)
ph_command(dch, ISAC_CMD_AR10);
else
ret = -EINVAL;
dch->inst.unlock(dch->inst.data);
dch->inst.unlock(dch->inst.privat);
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
dch->inst.lock(dch->inst.data,0);
dch->inst.lock(dch->inst.privat,0);
if (hh->dinfo == HW_RESET) {
if ((dch->ph_state == ISAC_IND_EI) ||
(dch->ph_state == ISAC_IND_DR) ||
@ -646,19 +641,19 @@ mISDN_ISAC_l1hw(mISDNif_t *hif, struct sk_buff *skb)
if (ISAC_TYPE_IOM1 & dch->type) {
/* IOM 1 Mode */
if (!tl) {
dch->write_reg(dch->inst.data, ISAC_SPCR, 0xa);
dch->write_reg(dch->inst.data, ISAC_ADF1, 0x2);
dch->write_reg(dch->inst.privat, ISAC_SPCR, 0xa);
dch->write_reg(dch->inst.privat, ISAC_ADF1, 0x2);
} else {
dch->write_reg(dch->inst.data, ISAC_SPCR, tl);
dch->write_reg(dch->inst.data, ISAC_ADF1, 0xa);
dch->write_reg(dch->inst.privat, ISAC_SPCR, tl);
dch->write_reg(dch->inst.privat, ISAC_ADF1, 0xa);
}
} else {
/* IOM 2 Mode */
dch->write_reg(dch->inst.data, ISAC_SPCR, tl);
dch->write_reg(dch->inst.privat, ISAC_SPCR, tl);
if (tl)
dch->write_reg(dch->inst.data, ISAC_ADF1, 0x8);
dch->write_reg(dch->inst.privat, ISAC_ADF1, 0x8);
else
dch->write_reg(dch->inst.data, ISAC_ADF1, 0x0);
dch->write_reg(dch->inst.privat, ISAC_ADF1, 0x0);
}
}
} else {
@ -667,7 +662,7 @@ mISDN_ISAC_l1hw(mISDNif_t *hif, struct sk_buff *skb)
hh->dinfo);
ret = -EINVAL;
}
dch->inst.unlock(dch->inst.data);
dch->inst.unlock(dch->inst.privat);
} else {
if (dch->debug & L1_DEB_WARN)
mISDN_debugprint(&dch->inst, "isac_l1hw unknown prim %x",
@ -705,13 +700,13 @@ dbusy_timer_handler(dchannel_t *dch)
int rbch, star;
if (test_bit(FLG_DBUSY_TIMER, &dch->DFlags)) {
if (dch->inst.lock(dch->inst.data, 1)) {
if (dch->inst.lock(dch->inst.privat, 1)) {
dch->dbusytimer.expires = jiffies + 1;
add_timer(&dch->dbusytimer);
return;
}
rbch = dch->read_reg(dch->inst.data, ISAC_RBCH);
star = dch->read_reg(dch->inst.data, ISAC_STAR);
rbch = dch->read_reg(dch->inst.privat, ISAC_RBCH);
star = dch->read_reg(dch->inst.privat, ISAC_STAR);
if (dch->debug)
mISDN_debugprint(&dch->inst, "D-Channel Busy RBCH %02x STAR %02x",
rbch, star);
@ -734,9 +729,9 @@ dbusy_timer_handler(dchannel_t *dch)
mISDN_debugprint(&dch->inst, "D-Channel Busy no tx_idx");
}
/* Transmitter reset */
dch->write_reg(dch->inst.data, ISAC_CMDR, 0x01);
dch->write_reg(dch->inst.privat, ISAC_CMDR, 0x01);
}
dch->inst.unlock(dch->inst.data);
dch->inst.unlock(dch->inst.privat);
}
}
@ -762,45 +757,45 @@ mISDN_isac_init(dchannel_t *dch)
isac->mocr = 0xaa;
if (dch->type & ISAC_TYPE_ISACSX) {
// clear LDD
dch->write_reg(dch->inst.data, ISACSX_TR_CONF0, 0x00);
dch->write_reg(dch->inst.privat, ISACSX_TR_CONF0, 0x00);
// enable transmitter
dch->write_reg(dch->inst.data, ISACSX_TR_CONF2, 0x00);
dch->write_reg(dch->inst.privat, ISACSX_TR_CONF2, 0x00);
// transparent mode 0, RAC, stop/go
dch->write_reg(dch->inst.data, ISACSX_MODED, 0xc9);
dch->write_reg(dch->inst.privat, ISACSX_MODED, 0xc9);
// all HDLC IRQ unmasked
dch->write_reg(dch->inst.data, ISACSX_MASKD, 0x03);
dch->write_reg(dch->inst.privat, ISACSX_MASKD, 0x03);
// unmask ICD, CID IRQs
dch->write_reg(dch->inst.data, ISACSX_MASK, ~(ISACSX_ISTA_ICD | ISACSX_ISTA_CIC));
dch->write_reg(dch->inst.privat, ISACSX_MASK, ~(ISACSX_ISTA_ICD | ISACSX_ISTA_CIC));
printk(KERN_INFO "mISDN_isac_init: ISACSX\n");
dchannel_sched_event(dch, D_L1STATECHANGE);
ph_command(dch, ISAC_CMD_RS);
} else { /* old isac */
dch->write_reg(dch->inst.data, ISAC_MASK, 0xff);
val = dch->read_reg(dch->inst.data, ISAC_RBCH);
dch->write_reg(dch->inst.privat, ISAC_MASK, 0xff);
val = dch->read_reg(dch->inst.privat, ISAC_RBCH);
printk(KERN_INFO "mISDN_isac_init: ISAC version (%x): %s\n", val, ISACVer[(val >> 5) & 3]);
dch->type |= ((val >> 5) & 3);
if (ISAC_TYPE_IOM1 & dch->type) {
/* IOM 1 Mode */
dch->write_reg(dch->inst.data, ISAC_ADF2, 0x0);
dch->write_reg(dch->inst.data, ISAC_SPCR, 0xa);
dch->write_reg(dch->inst.data, ISAC_ADF1, 0x2);
dch->write_reg(dch->inst.data, ISAC_STCR, 0x70);
dch->write_reg(dch->inst.data, ISAC_MODE, 0xc9);
dch->write_reg(dch->inst.privat, ISAC_ADF2, 0x0);
dch->write_reg(dch->inst.privat, ISAC_SPCR, 0xa);
dch->write_reg(dch->inst.privat, ISAC_ADF1, 0x2);
dch->write_reg(dch->inst.privat, ISAC_STCR, 0x70);
dch->write_reg(dch->inst.privat, ISAC_MODE, 0xc9);
} else {
/* IOM 2 Mode */
if (!isac->adf2)
isac->adf2 = 0x80;
dch->write_reg(dch->inst.data, ISAC_ADF2, isac->adf2);
dch->write_reg(dch->inst.data, ISAC_SQXR, 0x2f);
dch->write_reg(dch->inst.data, ISAC_SPCR, 0x00);
dch->write_reg(dch->inst.data, ISAC_STCR, 0x70);
dch->write_reg(dch->inst.data, ISAC_MODE, 0xc9);
dch->write_reg(dch->inst.data, ISAC_TIMR, 0x00);
dch->write_reg(dch->inst.data, ISAC_ADF1, 0x00);
dch->write_reg(dch->inst.privat, ISAC_ADF2, isac->adf2);
dch->write_reg(dch->inst.privat, ISAC_SQXR, 0x2f);
dch->write_reg(dch->inst.privat, ISAC_SPCR, 0x00);
dch->write_reg(dch->inst.privat, ISAC_STCR, 0x70);
dch->write_reg(dch->inst.privat, ISAC_MODE, 0xc9);
dch->write_reg(dch->inst.privat, ISAC_TIMR, 0x00);
dch->write_reg(dch->inst.privat, ISAC_ADF1, 0x00);
}
dchannel_sched_event(dch, D_L1STATECHANGE);
ph_command(dch, ISAC_CMD_RS);
dch->write_reg(dch->inst.data, ISAC_MASK, 0x0);
dch->write_reg(dch->inst.privat, ISAC_MASK, 0x0);
}
return 0;
}
@ -814,20 +809,20 @@ mISDN_clear_isac(dchannel_t *dch)
if (!isac)
return;
/* Disable all IRQ */
dch->write_reg(dch->inst.data, ISAC_MASK, 0xFF);
val = dch->read_reg(dch->inst.data, ISAC_STAR);
dch->write_reg(dch->inst.privat, ISAC_MASK, 0xFF);
val = dch->read_reg(dch->inst.privat, ISAC_STAR);
mISDN_debugprint(&dch->inst, "ISAC STAR %x", val);
val = dch->read_reg(dch->inst.data, ISAC_MODE);
val = dch->read_reg(dch->inst.privat, ISAC_MODE);
mISDN_debugprint(&dch->inst, "ISAC MODE %x", val);
val = dch->read_reg(dch->inst.data, ISAC_ADF2);
val = dch->read_reg(dch->inst.privat, ISAC_ADF2);
mISDN_debugprint(&dch->inst, "ISAC ADF2 %x", val);
val = dch->read_reg(dch->inst.data, ISAC_ISTA);
val = dch->read_reg(dch->inst.privat, ISAC_ISTA);
mISDN_debugprint(&dch->inst, "ISAC ISTA %x", val);
if (val & 0x01) {
eval = dch->read_reg(dch->inst.data, ISAC_EXIR);
eval = dch->read_reg(dch->inst.privat, ISAC_EXIR);
mISDN_debugprint(&dch->inst, "ISAC EXIR %x", eval);
}
val = dch->read_reg(dch->inst.data, ISAC_CIR0);
val = dch->read_reg(dch->inst.privat, ISAC_CIR0);
mISDN_debugprint(&dch->inst, "ISAC CIR0 %x", val);
dch->ph_state = (val >> 2) & 0xf;
}

View File

@ -133,4 +133,4 @@ extern void mISDN_isac_free(dchannel_t *);
extern void mISDN_isac_interrupt(dchannel_t *, u_char);
extern void mISDN_clear_isac(dchannel_t *);
extern int mISDN_ISAC_l1hw(mISDNif_t *, struct sk_buff *);
extern int mISDN_ISAC_l1hw(mISDNinstance_t *, struct sk_buff *);

View File

@ -37,7 +37,7 @@ static inline int
waitforHIA(bchannel_t *bch, int timeout)
{
while ((bch->Read_Reg(bch->inst.data, 0, ISAR_HIA) & 1) && timeout) {
while ((bch->Read_Reg(bch->inst.privat, 0, ISAR_HIA) & 1) && timeout) {
udelay(1);
timeout--;
}
@ -59,13 +59,13 @@ sendmsg(bchannel_t *bch, u_char his, u_char creg, u_char len,
if (bch->debug & L1_DEB_HSCX)
mISDN_debugprint(&bch->inst, "sendmsg(%02x,%02x,%d)", his, creg, len);
#endif
bch->Write_Reg(bch->inst.data, 0, ISAR_CTRL_H, creg);
bch->Write_Reg(bch->inst.data, 0, ISAR_CTRL_L, len);
bch->Write_Reg(bch->inst.data, 0, ISAR_WADR, 0);
bch->Write_Reg(bch->inst.privat, 0, ISAR_CTRL_H, creg);
bch->Write_Reg(bch->inst.privat, 0, ISAR_CTRL_L, len);
bch->Write_Reg(bch->inst.privat, 0, ISAR_WADR, 0);
if (msg && len) {
bch->Write_Reg(bch->inst.data, 1, ISAR_MBOX, msg[0]);
bch->Write_Reg(bch->inst.privat, 1, ISAR_MBOX, msg[0]);
for (i=1; i<len; i++)
bch->Write_Reg(bch->inst.data, 2, ISAR_MBOX, msg[i]);
bch->Write_Reg(bch->inst.privat, 2, ISAR_MBOX, msg[i]);
#if DUMP_MBOXFRAME>1
if (bch->debug & L1_DEB_HSCX_FIFO) {
char *t;
@ -81,7 +81,7 @@ sendmsg(bchannel_t *bch, u_char his, u_char creg, u_char len,
}
#endif
}
bch->Write_Reg(bch->inst.data, 1, ISAR_HIS, his);
bch->Write_Reg(bch->inst.privat, 1, ISAR_HIS, his);
waitforHIA(bch, 10000);
return(1);
}
@ -92,11 +92,11 @@ rcv_mbox(bchannel_t *bch, isar_reg_t *ireg, u_char *msg)
{
int i;
bch->Write_Reg(bch->inst.data, 1, ISAR_RADR, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_RADR, 0);
if (msg && ireg->clsb) {
msg[0] = bch->Read_Reg(bch->inst.data, 1, ISAR_MBOX);
msg[0] = bch->Read_Reg(bch->inst.privat, 1, ISAR_MBOX);
for (i=1; i < ireg->clsb; i++)
msg[i] = bch->Read_Reg(bch->inst.data, 2, ISAR_MBOX);
msg[i] = bch->Read_Reg(bch->inst.privat, 2, ISAR_MBOX);
#if DUMP_MBOXFRAME>1
if (bch->debug & L1_DEB_HSCX_FIFO) {
char *t;
@ -112,16 +112,16 @@ rcv_mbox(bchannel_t *bch, isar_reg_t *ireg, u_char *msg)
}
#endif
}
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
}
/* Call only with IRQ disabled !!! */
inline void
get_irq_infos(bchannel_t *bch, isar_reg_t *ireg)
{
ireg->iis = bch->Read_Reg(bch->inst.data, 1, ISAR_IIS);
ireg->cmsb = bch->Read_Reg(bch->inst.data, 1, ISAR_CTRL_H);
ireg->clsb = bch->Read_Reg(bch->inst.data, 1, ISAR_CTRL_L);
ireg->iis = bch->Read_Reg(bch->inst.privat, 1, ISAR_IIS);
ireg->cmsb = bch->Read_Reg(bch->inst.privat, 1, ISAR_CTRL_H);
ireg->clsb = bch->Read_Reg(bch->inst.privat, 1, ISAR_CTRL_L);
#if DUMP_MBOXFRAME
if (bch->debug & L1_DEB_HSCX)
mISDN_debugprint(&bch->inst, "rcv_mbox(%02x,%02x,%d)", ireg->iis, ireg->cmsb,
@ -137,7 +137,7 @@ waitrecmsg(bchannel_t *bch, u_char *len,
isar_hw_t *ih = bch->hw;
while((!(bch->Read_Reg(bch->inst.data, 0, ISAR_IRQBIT) & ISAR_IRQSTA)) &&
while((!(bch->Read_Reg(bch->inst.privat, 0, ISAR_IRQBIT) & ISAR_IRQSTA)) &&
(timeout++ < maxdelay))
udelay(1);
if (timeout >= maxdelay) {
@ -160,9 +160,9 @@ ISARVersion(bchannel_t *bch, char *s)
isar_hw_t *ih = bch->hw;
int debug;
// bch->cardmsg(bch->inst.data, CARD_RESET, NULL);
// bch->cardmsg(bch->inst.privat, CARD_RESET, NULL);
/* disable ISAR IRQ */
bch->Write_Reg(bch->inst.data, 0, ISAR_IRQBIT, 0);
bch->Write_Reg(bch->inst.privat, 0, ISAR_IRQBIT, 0);
debug = bch->debug;
bch->debug &= ~(L1_DEB_HSCX | L1_DEB_HSCX_FIFO);
if (!sendmsg(bch, ISAR_HIS_VNR, 0, 3, msg))
@ -196,11 +196,11 @@ isar_load_firmware(bchannel_t *bch, u_char *buf, int size)
u_short d_key;
} *blk_head;
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(bch->inst.privat, 0);
#define BLK_HEAD_SIZE 6
if (1 != (ret = ISARVersion(bch, "Testing"))) {
printk(KERN_ERR"isar_load_firmware wrong isar version %d\n", ret);
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(bch->inst.privat);
return(1);
}
debug = bch->debug;
@ -211,10 +211,10 @@ isar_load_firmware(bchannel_t *bch, u_char *buf, int size)
printk(KERN_DEBUG"isar_load_firmware size: %d\n", size);
cnt = 0;
/* disable ISAR IRQ */
bch->Write_Reg(bch->inst.data, 0, ISAR_IRQBIT, 0);
bch->Write_Reg(bch->inst.privat, 0, ISAR_IRQBIT, 0);
if (!(msg = kmalloc(256, GFP_ATOMIC))) {
printk(KERN_ERR"isar_load_firmware no buffer\n");
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(bch->inst.privat);
return (1);
}
while (cnt < size) {
@ -320,8 +320,8 @@ isar_load_firmware(bchannel_t *bch, u_char *buf, int size)
printk(KERN_DEBUG"isar start dsp success\n");
/* NORMAL mode entered */
/* Enable IRQs of ISAR */
bch->Write_Reg(bch->inst.data, 0, ISAR_IRQBIT, ISAR_IRQSTA);
bch->inst.unlock(bch->inst.data);
bch->Write_Reg(bch->inst.privat, 0, ISAR_IRQBIT, ISAR_IRQSTA);
bch->inst.unlock(bch->inst.privat);
cnt = 1000; /* max 1s */
while ((!ih->reg->bstat) && cnt) {
mdelay(1);
@ -340,12 +340,12 @@ isar_load_firmware(bchannel_t *bch, u_char *buf, int size)
while (cnt--)
mdelay(1);
ih->reg->iis = 0;
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(bch->inst.privat, 0);
if (!sendmsg(bch, ISAR_HIS_DIAG, ISAR_CTRL_STST, 0, NULL)) {
printk(KERN_ERR"isar sendmsg self tst failed\n");
ret = 1;goto reterror;
}
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(bch->inst.privat);
cnt = 10000; /* max 100 ms */
while ((ih->reg->iis != ISAR_IIS_DIAG) && cnt) {
udelay(10);
@ -364,13 +364,13 @@ isar_load_firmware(bchannel_t *bch, u_char *buf, int size)
ih->reg->cmsb, ih->reg->clsb, ih->reg->par[0]);
ret = 1;goto reterrflg;
}
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(bch->inst.privat, 0);
ih->reg->iis = 0;
if (!sendmsg(bch, ISAR_HIS_DIAG, ISAR_CTRL_SWVER, 0, NULL)) {
printk(KERN_ERR"isar RQST SVN failed\n");
ret = 1;goto reterror;
}
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(bch->inst.privat);
cnt = 30000; /* max 300 ms */
while ((ih->reg->iis != ISAR_IIS_DIAG) && cnt) {
udelay(10);
@ -392,19 +392,19 @@ isar_load_firmware(bchannel_t *bch, u_char *buf, int size)
}
}
bch->debug = debug;
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(bch->inst.privat, 0);
isar_setup(bch);
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(bch->inst.privat);
bch->inst.obj->own_ctrl(&bch->inst, MGR_LOADFIRM | CONFIRM, NULL);
ret = 0;
reterrflg:
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(bch->inst.privat, 0);
reterror:
bch->debug = debug;
if (ret)
/* disable ISAR IRQ */
bch->Write_Reg(bch->inst.data, 0, ISAR_IRQBIT, 0);
bch->inst.unlock(bch->inst.data);
bch->Write_Reg(bch->inst.privat, 0, ISAR_IRQBIT, 0);
bch->inst.unlock(bch->inst.privat);
kfree(msg);
return(ret);
}
@ -421,7 +421,7 @@ deliver_status(bchannel_t *bch, int status)
{
if (bch->debug & L1_DEB_HSCX)
mISDN_debugprint(&bch->inst, "HL->LL FAXIND %x", status);
if_link(&bch->inst.up, PH_STATUS | INDICATION, status, 0, NULL, 0);
mISDN_queue_data(&bch->inst, FLG_MSG_UP, PH_STATUS | INDICATION, status, 0, NULL, 0);
}
static void
@ -448,7 +448,7 @@ isar_bh(bchannel_t *bch)
else if (tt > '9')
tt += 7;
tt |= DTMF_TONE_VAL;
if_link(&bch->inst.up, PH_CONTROL | INDICATION,
mISDN_queue_data(&bch->inst, FLG_MSG_UP, PH_CONTROL | INDICATION,
0, sizeof(int), &tt, 0);
}
}
@ -462,7 +462,7 @@ isar_rcv_frame(bchannel_t *bch)
if (!ih->reg->clsb) {
mISDN_debugprint(&bch->inst, "isar zero len frame");
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
return;
}
switch (bch->protocol) {
@ -471,7 +471,7 @@ isar_rcv_frame(bchannel_t *bch)
ih->reg->iis, ih->reg->cmsb, ih->reg->clsb);
printk(KERN_WARNING"isar protocol 0 spurious IIS_RDATA %x/%x/%x\n",
ih->reg->iis, ih->reg->cmsb, ih->reg->clsb);
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
break;
case ISDN_PID_L1_B_64TRANS:
case ISDN_PID_L2_B_TRANSDTMF:
@ -482,14 +482,14 @@ isar_rcv_frame(bchannel_t *bch)
bch_sched_event(bch, B_RCVBUFREADY);
} else {
printk(KERN_WARNING "mISDN: skb out of memory\n");
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
}
break;
case ISDN_PID_L1_B_64HDLC:
if ((bch->rx_idx + ih->reg->clsb) > MAX_DATA_MEM) {
if (bch->debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "isar_rcv_frame: incoming packet too large");
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
bch->rx_idx = 0;
} else if (ih->reg->cmsb & HDLC_ERROR) {
if (bch->debug & L1_DEB_WARN)
@ -502,7 +502,7 @@ isar_rcv_frame(bchannel_t *bch)
bch->err_crc++;
#endif
bch->rx_idx = 0;
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
} else {
if (ih->reg->cmsb & HDLC_FSD)
bch->rx_idx = 0;
@ -530,7 +530,7 @@ isar_rcv_frame(bchannel_t *bch)
if (ih->state != STFAX_ACTIV) {
if (bch->debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "isar_rcv_frame: not ACTIV");
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
bch->rx_idx = 0;
break;
}
@ -544,7 +544,7 @@ isar_rcv_frame(bchannel_t *bch)
if (ih->reg->cmsb & SART_NMD) { /* ABORT */
if (bch->debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "isar_rcv_frame: no more data");
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
bch->rx_idx = 0;
sendmsg(bch, SET_DPS(ih->dpath) |
ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
@ -558,7 +558,7 @@ isar_rcv_frame(bchannel_t *bch)
bch_sched_event(bch, B_LL_NOCARRIER);
} else {
printk(KERN_WARNING "mISDN: skb out of memory\n");
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
}
break;
}
@ -566,7 +566,7 @@ isar_rcv_frame(bchannel_t *bch)
if (bch->debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "isar_rcv_frame: unknown fax mode %x",
ih->cmd);
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
bch->rx_idx = 0;
break;
}
@ -574,14 +574,14 @@ isar_rcv_frame(bchannel_t *bch)
if ((bch->rx_idx + ih->reg->clsb) > MAX_DATA_MEM) {
if (bch->debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "isar_rcv_frame: incoming packet too large");
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
bch->rx_idx = 0;
} else if (ih->reg->cmsb & HDLC_ERROR) {
if (bch->debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "isar frame error %x len %d",
ih->reg->cmsb, ih->reg->clsb);
bch->rx_idx = 0;
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
} else {
if (ih->reg->cmsb & HDLC_FSD)
bch->rx_idx = 0;
@ -609,7 +609,7 @@ isar_rcv_frame(bchannel_t *bch)
if (ih->reg->cmsb & SART_NMD) { /* ABORT */
if (bch->debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "isar_rcv_frame: no more data");
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
bch->rx_idx = 0;
sendmsg(bch, SET_DPS(ih->dpath) |
ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL);
@ -619,7 +619,7 @@ isar_rcv_frame(bchannel_t *bch)
break;
default:
printk(KERN_ERR"isar_rcv_frame protocol (%x)error\n", bch->protocol);
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
break;
}
}
@ -1130,11 +1130,11 @@ isar_int_main(bchannel_t *bch)
} else {
mISDN_debugprint(&bch->inst, "isar spurious IIS_RDATA %x/%x/%x",
ih->reg->iis, ih->reg->cmsb, ih->reg->clsb);
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
}
break;
case ISAR_IIS_GSTEV:
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
ih->reg->bstat |= ih->reg->cmsb;
check_send(bch, ih->reg->cmsb);
break;
@ -1150,7 +1150,7 @@ isar_int_main(bchannel_t *bch)
if (bch->debug & L1_DEB_WARN)
mISDN_debugprint(&bch->inst, "Buffer STEV dpath%d msb(%x)",
ih->reg->iis>>6, ih->reg->cmsb);
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
break;
case ISAR_IIS_PSTEV:
if ((bc = sel_bch_isar(bch, ih->reg->iis >> 6))) {
@ -1171,7 +1171,7 @@ isar_int_main(bchannel_t *bch)
} else {
mISDN_debugprint(&bch->inst, "isar spurious IIS_PSTEV %x/%x/%x",
ih->reg->iis, ih->reg->cmsb, ih->reg->clsb);
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
}
break;
case ISAR_IIS_PSTRSP:
@ -1181,7 +1181,7 @@ isar_int_main(bchannel_t *bch)
} else {
mISDN_debugprint(&bch->inst, "isar spurious IIS_PSTRSP %x/%x/%x",
ih->reg->iis, ih->reg->cmsb, ih->reg->clsb);
bch->Write_Reg(bch->inst.data, 1, ISAR_IIA, 0);
bch->Write_Reg(bch->inst.privat, 1, ISAR_IIA, 0);
}
break;
case ISAR_IIS_DIAG:
@ -1542,16 +1542,14 @@ isar_setup(bchannel_t *bch)
}
int
isar_down(mISDNif_t *hif, struct sk_buff *skb)
isar_down(mISDNinstance_t *inst, struct sk_buff *skb)
{
bchannel_t *bch;
int ret = -EINVAL;
mISDN_head_t *hh;
if (!hif || !skb)
return(ret);
hh = mISDN_HEAD_P(skb);
bch = hif->fdata;
bch = container_of(inst, bchannel_t, inst);
ret = 0;
if ((hh->prim == PH_DATA_REQ) ||
(hh->prim == (DL_DATA | REQUEST))) {
@ -1559,20 +1557,20 @@ isar_down(mISDNif_t *hif, struct sk_buff *skb)
mISDN_debugprint(&bch->inst, " l2l1 next_skb exist this shouldn't happen");
return(-EBUSY);
}
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(bch->inst.privat, 0);
if (test_and_set_bit(BC_FLG_TX_BUSY, &bch->Flag)) {
test_and_set_bit(BC_FLG_TX_NEXT, &bch->Flag);
bch->next_skb = skb;
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(bch->inst.privat);
return(0);
} else {
bch->tx_len = skb->len;
memcpy(bch->tx_buf, skb->data, bch->tx_len);
bch->tx_idx = 0;
isar_fill_fifo(bch);
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(bch->inst.privat);
skb_trim(skb, 0);
return(if_newhead(&bch->inst.up, hh->prim | CONFIRM,
return(mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM,
hh->dinfo, skb));
}
} else if ((hh->prim == (PH_ACTIVATE | REQUEST)) ||
@ -1587,16 +1585,16 @@ isar_down(mISDNif_t *hif, struct sk_buff *skb)
if ((bp == ISDN_PID_L1_B_64TRANS) &&
(bch->inst.pid.protocol[2] == ISDN_PID_L2_B_TRANSDTMF))
bp = ISDN_PID_L2_B_TRANSDTMF;
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(bch->inst.privat, 0);
ret = modeisar(bch, bch->channel, bp, NULL);
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(bch->inst.privat);
}
skb_trim(skb, 0);
return(if_newhead(&bch->inst.up, hh->prim | CONFIRM, ret, 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))) {
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(bch->inst.privat, 0);
if (test_and_clear_bit(BC_FLG_TX_NEXT, &bch->Flag)) {
dev_kfree_skb(bch->next_skb);
bch->next_skb = NULL;
@ -1604,10 +1602,10 @@ isar_down(mISDNif_t *hif, struct sk_buff *skb)
test_and_clear_bit(BC_FLG_TX_BUSY, &bch->Flag);
modeisar(bch, bch->channel, 0, NULL);
test_and_clear_bit(BC_FLG_ACTIV, &bch->Flag);
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(bch->inst.privat);
skb_trim(skb, 0);
if (hh->prim != (MGR_DISCONNECT | REQUEST))
if (!if_newhead(&bch->inst.up, hh->prim | CONFIRM, 0, skb))
if (!mISDN_queueup_newhead(inst, 0, hh->prim | CONFIRM, 0, skb))
return(0);
} else if (hh->prim == (PH_CONTROL | REQUEST)) {
int *val;
@ -1628,12 +1626,11 @@ isar_down(mISDNif_t *hif, struct sk_buff *skb)
else if (tt > '9')
tt -= 7;
tt &= 0x1f;
bch->inst.lock(bch->inst.data, 0);
bch->inst.lock(bch->inst.privat, 0);
isar_pump_cmd(bch, PCTRL_CMD_TDTMF, tt);
bch->inst.unlock(bch->inst.data);
bch->inst.unlock(bch->inst.privat);
skb_trim(skb, 0);
if (!if_newhead(&bch->inst.up, PH_CONTROL |
CONFIRM, 0, skb))
if (!mISDN_queueup_newhead(inst, 0, PH_CONTROL | CONFIRM, 0, skb))
return(0);
} else {
printk(KERN_WARNING "isar_down TOUCH_TONE_SEND wrong protocol %x\n",
@ -1666,16 +1663,14 @@ isar_down(mISDNif_t *hif, struct sk_buff *skb)
}
fw_p = firmware;
skb_trim(skb, 0);
if(!if_newhead(&bch->inst.up, PH_CONTROL | CONFIRM,
0, skb))
if(!mISDN_queueup_newhead(inst, 0, PH_CONTROL | CONFIRM, 0, skb))
return(0);
} else if (hh->dinfo == HW_FIRM_DATA) {
len = *val++;
memcpy(fw_p, val, len);
fw_p += len;
skb_trim(skb, 0);
if(!if_newhead(&bch->inst.up, PH_CONTROL | CONFIRM,
0, skb))
if(!mISDN_queueup_newhead(inst, 0, PH_CONTROL | CONFIRM, 0, skb))
return(0);
} else if (hh->dinfo == HW_FIRM_END) {
if ((fw_p - firmware) == firmwaresize)
@ -1689,8 +1684,7 @@ isar_down(mISDNif_t *hif, struct sk_buff *skb)
fw_p = firmware = NULL;
firmwaresize = 0;
skb_trim(skb, 0);
if(!if_newhead(&bch->inst.up, PH_CONTROL | CONFIRM,
0, skb))
if(!mISDN_queueup_newhead(inst, 0, PH_CONTROL | CONFIRM, 0, skb))
return(0);
}
} else {

View File

@ -234,5 +234,5 @@ extern int ISARVersion(bchannel_t *bch, char *s);
extern void isar_int_main(bchannel_t *bch);
extern int init_isar(bchannel_t *bch);
extern void free_isar(bchannel_t *bch);
extern int isar_down(mISDNif_t *, struct sk_buff *);
extern int isar_down(mISDNinstance_t *, struct sk_buff *);
extern int isar_load_firmware(bchannel_t *bch, u_char *buf, int size);

View File

@ -1932,7 +1932,7 @@ global_handler(layer3_t *l3, u_int mt, struct sk_buff *skb)
}
static int
dss1_fromdown(mISDNif_t *hif, struct sk_buff *skb)
dss1_fromdown(mISDNinstance_t *inst, struct sk_buff *skb)
{
layer3_t *l3;
u_int i;
@ -1941,11 +1941,8 @@ dss1_fromdown(mISDNif_t *hif, struct sk_buff *skb)
l3_process_t *proc;
mISDN_head_t *hh;
Q931_info_t *qi;
if (!hif || !skb)
return(ret);
l3 = hif->fdata;
l3 = inst->privat;
hh = mISDN_HEAD_P(skb);
if (debug)
printk(KERN_DEBUG "%s: prim(%x)\n", __FUNCTION__, hh->prim);
@ -2119,7 +2116,7 @@ dss1_fromdown(mISDNif_t *hif, struct sk_buff *skb)
}
static int
dss1_fromup(mISDNif_t *hif, struct sk_buff *skb)
dss1_fromup(mISDNinstance_t *inst, struct sk_buff *skb)
{
layer3_t *l3;
u_int i;
@ -2127,9 +2124,7 @@ dss1_fromup(mISDNif_t *hif, struct sk_buff *skb)
l3_process_t *proc;
mISDN_head_t *hh;
if (!hif || !skb)
return(ret);
l3 = hif->fdata;
l3 = inst->privat;
hh = mISDN_HEAD_P(skb);
if (debug)
printk(KERN_DEBUG "%s: prim(%x)\n", __FUNCTION__, hh->prim);
@ -2223,6 +2218,7 @@ release_udss1(layer3_t *l3)
printk(KERN_DEBUG "release_udss1 refcnt %d l3(%p) inst(%p)\n",
u_dss1.refcnt, l3, inst);
release_l3(l3);
#ifdef FIXME
if (inst->up.peer) {
inst->up.peer->obj->ctrl(inst->up.peer,
MGR_DISCONNECT | REQUEST, &inst->up);
@ -2231,6 +2227,7 @@ release_udss1(layer3_t *l3)
inst->down.peer->obj->ctrl(inst->down.peer,
MGR_DISCONNECT | REQUEST, &inst->down);
}
#endif
list_del(&l3->list);
u_dss1.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
if (l3->entity != MISDN_ENTITY_NONE)
@ -2365,6 +2362,7 @@ udss1_manager(void *data, u_int prim, void *arg) {
l3l->down_headerlen = ((mISDN_stPara_t *)arg)->down_headerlen;
case MGR_CLRSTPARA | INDICATION:
break;
#ifdef FIXME
case MGR_CONNECT | REQUEST:
return(mISDN_ConnectIF(inst, arg));
case MGR_SETIF | REQUEST:
@ -2373,6 +2371,7 @@ udss1_manager(void *data, u_int prim, void *arg) {
case MGR_DISCONNECT | REQUEST:
case MGR_DISCONNECT | INDICATION:
return(mISDN_DisConnectIF(inst, arg));
#endif
case MGR_RELEASE | INDICATION:
case MGR_UNREGLAYER | REQUEST:
if (debug & 0x1000)

View File

@ -166,13 +166,13 @@ l1m_debug(struct FsmInst *fi, char *fmt, ...)
static int
l1up(layer1_t *l1, u_int prim, int dinfo, int len, void *arg)
{
return(if_link(&l1->inst.up, prim, dinfo, len, arg, 0));
return(mISDN_queue_data(&l1->inst, FLG_MSG_UP, prim, dinfo, len, arg, 0));
}
static int
l1down(layer1_t *l1, u_int prim, int dinfo, int len, void *arg)
{
return(if_link(&l1->inst.down, prim, dinfo, len, arg, 0));
return(mISDN_queue_data(&l1->inst, FLG_MSG_DOWN, prim, dinfo, len, arg, 0));
}
static void
@ -491,24 +491,18 @@ static struct FsmNode L1BFnList[] =
#define L1B_FN_COUNT (sizeof(L1BFnList)/sizeof(struct FsmNode))
static int
l1from_up(mISDNif_t *hif, struct sk_buff *skb)
l1from_up(mISDNinstance_t *inst, struct sk_buff *skb)
{
layer1_t *l1;
mISDN_head_t *hh;
int err = 0;
if (!hif || !hif->fdata || !skb)
return(-EINVAL);
l1 = hif->fdata;
l1 = inst->privat;
hh = mISDN_HEAD_P(skb);
switch(hh->prim) {
case (PH_DATA | REQUEST):
case (PH_CONTROL | REQUEST):
if (l1->inst.down.func)
return(l1->inst.down.func(&l1->inst.down,
skb));
else
err = -ENXIO;
return(mISDN_queue_down(inst, 0, skb));
break;
case (PH_ACTIVATE | REQUEST):
if (test_bit(FLG_L1_ACTIVATED, &l1->Flags))
@ -519,10 +513,7 @@ l1from_up(mISDNif_t *hif, struct sk_buff *skb)
}
break;
case (MDL_FINDTEI | REQUEST):
if (l1->inst.up.func)
return(l1->inst.up.func(&l1->inst.up, skb));
else
err = -ENXIO;
return(mISDN_queue_up(inst, 0, skb));
break;
default:
if (l1->debug)
@ -537,28 +528,20 @@ l1from_up(mISDNif_t *hif, struct sk_buff *skb)
}
static int
l1from_down(mISDNif_t *hif, struct sk_buff *skb)
l1from_down(mISDNinstance_t *inst, struct sk_buff *skb)
{
layer1_t *l1;
mISDN_head_t *hh;
int err = 0;
if (!hif || !hif->fdata || !skb)
return(-EINVAL);
l1 = hif->fdata;
l1 = inst->privat;
hh = mISDN_HEAD_P(skb);
if (hh->prim == PH_DATA_IND) {
if (test_bit(FLG_L1_ACTTIMER, &l1->Flags))
mISDN_FsmEvent(&l1->l1m, EV_TIMER_ACT, NULL);
if (l1->inst.up.func)
return(l1->inst.up.func(&l1->inst.up, skb));
else
err = -ENXIO;
return(mISDN_queue_up(inst, 0, skb));
} else if (hh->prim == PH_DATA_CNF) {
if (l1->inst.up.func)
return(l1->inst.up.func(&l1->inst.up, skb));
else
err = -ENXIO;
return(mISDN_queue_up(inst, 0, skb));
} else if (hh->prim == (PH_CONTROL | INDICATION)) {
if (hh->dinfo == HW_RESET)
mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL);
@ -605,6 +588,7 @@ release_l1(layer1_t *l1) {
mISDNinstance_t *inst = &l1->inst;
mISDN_FsmDelTimer(&l1->timer, 0);
#ifdef OBSOLATE
if (inst->up.peer) {
inst->up.peer->obj->ctrl(inst->up.peer,
MGR_DISCONNECT | REQUEST, &inst->up);
@ -613,6 +597,7 @@ release_l1(layer1_t *l1) {
inst->down.peer->obj->ctrl(inst->down.peer,
MGR_DISCONNECT | REQUEST, &inst->down);
}
#endif
list_del(&l1->list);
isdnl1.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
kfree(l1);
@ -722,6 +707,7 @@ l1_manager(void *data, u_int prim, void *arg) {
case MGR_NEWLAYER | REQUEST:
err = new_l1(data, arg);
break;
#ifdef OBSOLATE
case MGR_CONNECT | REQUEST:
err = mISDN_ConnectIF(inst, arg);
break;
@ -733,6 +719,7 @@ l1_manager(void *data, u_int prim, void *arg) {
case MGR_DISCONNECT | INDICATION:
err = mISDN_DisConnectIF(inst, arg);
break;
#endif
case MGR_UNREGLAYER | REQUEST:
case MGR_RELEASE | INDICATION:
printk(KERN_DEBUG "release_l1 id %x\n", l1l->inst.st->id);

View File

@ -131,22 +131,20 @@ l2_newid(layer2_t *l2)
static int
l2up(layer2_t *l2, u_int prim, int dinfo, struct sk_buff *skb)
{
return(if_newhead(&l2->inst.up, prim, dinfo, skb));
return(mISDN_queueup_newhead(&l2->inst, 0, prim, dinfo, skb));
}
static int
l2up_create(layer2_t *l2, u_int prim, int dinfo, int len, void *arg)
{
return(if_link(&l2->inst.up, prim, dinfo, len, arg, 0));
return(mISDN_queue_data(&l2->inst, FLG_MSG_UP, prim, dinfo, len, arg, 0));
}
static int
l2down_skb(layer2_t *l2, struct sk_buff *skb) {
mISDNif_t *down = &l2->inst.down;
int ret = -ENXIO;
int ret;
if (down->func)
ret = down->func(down, skb);
ret = mISDN_queue_down(&l2->inst, 0, skb);
if (ret && l2->debug)
printk(KERN_DEBUG "l2down_skb: ret(%d)\n", ret);
return(ret);
@ -190,17 +188,15 @@ l2down_create(layer2_t *l2, u_int prim, int dinfo, int len, void *arg)
}
static int
l2_chain_down(mISDNif_t *hif, struct sk_buff *skb) {
if (!hif || !hif->fdata)
return(-EINVAL);
return(l2down_raw(hif->fdata, skb));
l2_chain_down(mISDNinstance_t *inst, struct sk_buff *skb) {
return(l2down_raw(inst->privat, skb));
}
static int
ph_data_confirm(mISDNif_t *up, mISDN_head_t *hh, struct sk_buff *skb) {
layer2_t *l2 = up->fdata;
ph_data_confirm(mISDNinstance_t *inst, mISDN_head_t *hh, struct sk_buff *skb) {
layer2_t *l2 = inst->privat;
struct sk_buff *nskb = skb;
mISDNif_t *next = up->clone;
// mISDNif_t *next = up->clone;
int ret = -EAGAIN;
if (test_bit(FLG_L1_BUSY, &l2->flag)) {
@ -213,8 +209,10 @@ ph_data_confirm(mISDNif_t *up, mISDN_head_t *hh, struct sk_buff *skb) {
}
} else
l2->down_id = MISDN_ID_NONE;
#ifdef FIXME
if (next)
ret = next->func(next, skb);
#endif
if (ret) {
dev_kfree_skb(skb);
ret = 0;
@ -225,8 +223,10 @@ ph_data_confirm(mISDNif_t *up, mISDN_head_t *hh, struct sk_buff *skb) {
}
}
}
#ifdef FIXME
if (ret && next)
ret = next->func(next, skb);
#endif
if (!test_and_set_bit(FLG_L1_BUSY, &l2->flag)) {
if ((nskb = skb_dequeue(&l2->down_queue))) {
l2->down_id = mISDN_HEAD_DINFO(nskb);
@ -1880,27 +1880,25 @@ ph_data_indication(layer2_t *l2, mISDN_head_t *hh, struct sk_buff *skb) {
}
static int
l2from_down(mISDNif_t *hif, struct sk_buff *askb)
l2from_down(mISDNinstance_t *inst, struct sk_buff *askb)
{
layer2_t *l2;
int ret = -EINVAL;
struct sk_buff *cskb = askb;
mISDNif_t *next;
mISDN_head_t *hh, sh;
if (!hif || !askb)
return(-EINVAL);
l2 = hif->fdata;
l2 = inst->privat;
hh = mISDN_HEAD_P(askb);
next = hif->clone;
// printk(KERN_DEBUG "%s: prim(%x)\n", __FUNCTION__, hh->prim);
if (!l2) {
#ifdef FIXME
if (next && next->func)
ret = next->func(next, askb);
#endif
return(ret);
}
if (hh->prim == (PH_DATA | CONFIRM))
return(ph_data_confirm(hif, hh, askb));
return(ph_data_confirm(inst, hh, askb));
if (hh->prim == (MDL_FINDTEI | REQUEST)) {
ret = -ESRCH;
if (test_bit(FLG_LAPD, &l2->flag)) {
@ -1914,10 +1912,13 @@ l2from_down(mISDNif_t *hif, struct sk_buff *askb)
}
}
}
#ifdef FIXME
if (next && next->func)
ret = next->func(next, askb);
#endif
return(ret);
}
#ifdef FIXME
if (next) {
if (next->func) {
if (!(cskb = skb_clone(askb, GFP_ATOMIC)))
@ -1926,6 +1927,7 @@ l2from_down(mISDNif_t *hif, struct sk_buff *askb)
sh = *hh;
}
}
#endif
switch (hh->prim) {
case (PH_DATA_IND):
ret = ph_data_indication(l2, hh, cskb);
@ -1962,22 +1964,22 @@ l2from_down(mISDNif_t *hif, struct sk_buff *askb)
dev_kfree_skb(cskb);
ret = 0;
}
#ifdef FIXME
if (next && next->func) {
*hh = sh;
ret = next->func(next, askb);
}
#endif
return(ret);
}
static int
l2from_up(mISDNif_t *hif, struct sk_buff *skb) {
l2from_up(mISDNinstance_t *inst, struct sk_buff *skb) {
layer2_t *l2;
mISDN_head_t *hh;
int ret = -EINVAL;
if (!hif || !skb)
return(ret);
l2 = hif->fdata;
l2 = inst->privat;
hh = mISDN_HEAD_P(skb);
// printk(KERN_DEBUG "%s: prim(%x)\n", __FUNCTION__, hh->prim);
if (!l2)
@ -2087,6 +2089,7 @@ release_l2(layer2_t *l2)
ReleaseWin(l2);
if (test_bit(FLG_LAPD, &l2->flag))
release_tei(l2->tm);
#ifdef OBSOLATE
if (inst->up.peer) {
inst->up.peer->obj->ctrl(inst->up.peer,
MGR_DISCONNECT | REQUEST, &inst->up);
@ -2108,6 +2111,7 @@ release_l2(layer2_t *l2)
kfree(l2->cloneif);
l2->cloneif = NULL;
}
#endif
list_del(&l2->list);
isdnl2.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
if (l2->entity != MISDN_ENTITY_NONE)
@ -2262,7 +2266,6 @@ static int
clone_l2(layer2_t *l2, mISDNinstance_t **new_ip) {
int err;
layer2_t *nl2;
mISDNif_t *nif;
mISDNstack_t *st;
if (!l2)
@ -2272,19 +2275,12 @@ clone_l2(layer2_t *l2, mISDNinstance_t **new_ip) {
st = (mISDNstack_t *)*new_ip;
if (!st)
return(-EINVAL);
if (!l2->inst.down.peer)
return(-EINVAL);
if (!(nif = kmalloc(sizeof(mISDNif_t), GFP_ATOMIC))) {
printk(KERN_ERR "clone l2 no if mem\n");
return(-ENOMEM);
}
err = new_l2(st, &l2->inst.pid, &nl2);
if (err) {
kfree(nif);
printk(KERN_ERR "clone l2 failed err(%d)\n", err);
return(err);
}
memset(nif, 0, sizeof(mISDNif_t));
#ifdef FIXME
nl2->cloneif = nif;
nif->func = l2from_down;
nif->fdata = nl2;
@ -2300,6 +2296,7 @@ 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);
}
@ -2388,6 +2385,7 @@ l2_manager(void *data, u_int prim, void *arg) {
break;
case MGR_CLONELAYER | REQUEST:
return(clone_l2(l2l, arg));
#ifdef OBSOLATE
case MGR_CONNECT | REQUEST:
return(mISDN_ConnectIF(inst, arg));
case MGR_SETIF | REQUEST:
@ -2405,6 +2403,7 @@ l2_manager(void *data, u_int prim, void *arg) {
case MGR_DISCONNECT | REQUEST:
case MGR_DISCONNECT | INDICATION:
return(mISDN_DisConnectIF(inst, arg));
#endif
case MGR_RELEASE | INDICATION:
case MGR_UNREGLAYER | REQUEST:
release_l2(l2l);

View File

@ -47,7 +47,7 @@ typedef struct _layer2 {
int T200, N200, T203;
int debug;
mISDNinstance_t inst;
mISDNif_t *cloneif;
// mISDNif_t *cloneif;
int next_id;
u_int down_id;
struct sk_buff *windowar[MAX_WINDOW];

View File

@ -369,9 +369,9 @@ mISDN_l3up(l3_process_t *l3p, u_int prim, struct sk_buff *skb)
return(-EINVAL);
l3 = l3p->l3;
if (!skb)
err = if_link(&l3->inst.up, prim, l3p->id, 0, NULL, 0);
err = mISDN_queue_data(&l3->inst, FLG_MSG_UP, prim, l3p->id, 0, NULL, 0);
else
err = if_newhead(&l3->inst.up, prim, l3p->id, skb);
err = mISDN_queueup_newhead(&l3->inst, 0, prim, l3p->id, skb);
return(err);
}
@ -380,9 +380,9 @@ l3down(layer3_t *l3, u_int prim, int dinfo, struct sk_buff *skb) {
int err = -EINVAL;
if (!skb)
err = if_link(&l3->inst.down, prim, dinfo, 0, NULL, 0);
err = mISDN_queue_data(&l3->inst, FLG_MSG_DOWN, prim, dinfo, 0, NULL, 0);
else
err = if_newhead(&l3->inst.down, prim, dinfo, skb);
err = mISDN_queuedown_newhead(&l3->inst, 0, prim, dinfo, skb);
return(err);
}

View File

@ -315,7 +315,7 @@ int ControllerReleasePlci(Plci_t *);
Application_t *getApplication4Id(Controller_t *, __u16);
Plci_t *getPlci4Addr(Controller_t *, __u32);
int ControllerL4L3(Controller_t *, u_int, int, struct sk_buff *);
int ControllerL3L4(mISDNif_t *, struct sk_buff *);
int ControllerL3L4(mISDNinstance_t *, struct sk_buff *);
PLInst_t *ControllerSelChannel(Controller_t *, u_int);
void ControllerAddSSProcess(Controller_t *, SSProcess_t *);
SSProcess_t *getSSProcess4Id(Controller_t *, __u16);

View File

@ -173,9 +173,9 @@ SKB2Application(Ncci_t *ncci, struct sk_buff *skb)
static inline int
SKB_l4l3(Ncci_t *ncci, struct sk_buff *skb)
{
if (!ncci->link || !ncci->link->inst.down.func)
if (!ncci->link || !ncci->link->inst.func)
return(-ENXIO);
return(ncci->link->inst.down.func(&ncci->link->inst.down, skb));
return(mISDN_queue_down(&ncci->link->inst, 0, skb));
}
static inline void
@ -732,7 +732,7 @@ ncciD_disconnect_b3_ind(struct FsmInst *fi, int event, void *arg)
skb_pull(skb, CAPIMSG_BASELEN);
skb_trim(skb, 0);
skb_put(skb, 4);
if_newhead(&ncci->link->inst.down, CAPI_DISCONNECT_B3_RESP, 0, skb);
mISDN_queuedown_newhead(&ncci->link->inst, 0, CAPI_DISCONNECT_B3_RESP, 0, skb);
ncciDestr(ncci);
} else
SKB2Application(ncci, arg);
@ -768,7 +768,7 @@ ncciD_appl_release_disc(struct FsmInst *fi, int event, void *arg)
capimsg_setu32(parm, 0, ncci->addr);
parm[4] = 0;
mISDN_FsmChangeState(fi, ST_NCCI_N_4);
if_link(&ncci->link->inst.down, CAPI_DISCONNECT_B3_REQ, 0, 5, parm, 0);
mISDN_queue_data(&ncci->link->inst, FLG_MSG_DOWN, CAPI_DISCONNECT_B3_REQ, 0, 5, parm, 0);
}
static struct FsmNode fn_ncciD_list[] =
@ -1400,10 +1400,9 @@ ncciL4L3(Ncci_t *ncci, u_int prim, int dtyp, int len, void *arg, struct sk_buff
capidebug(CAPI_DBG_NCCI_L3, "%s: NCCI %x prim(%x) dtyp(%x) len(%d) skb(%p)",
__FUNCTION__, ncci->addr, prim, dtyp, len, skb);
if (skb)
return(if_newhead(&ncci->link->inst.down, prim, dtyp, skb));
return(mISDN_queuedown_newhead(&ncci->link->inst, 0, prim, dtyp, skb));
else
return(if_link(&ncci->link->inst.down, prim, dtyp,
len, arg, 8));
return(mISDN_queue_data(&ncci->link->inst, FLG_MSG_DOWN, prim, dtyp, len, arg, 8));
}
void

View File

@ -579,7 +579,9 @@ release_card(sedl_fax *card) {
mISDN_free_bch(&card->bch[1]);
mISDN_free_bch(&card->bch[0]);
mISDN_free_dch(&card->dch);
#ifdef OBSOLATE
speedfax.ctrl(card->dch.inst.up.peer, MGR_DISCONNECT | REQUEST, &card->dch.inst.up);
#endif
speedfax.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
list_del(&card->list);
unlock_dev(card);
@ -637,21 +639,21 @@ speedfax_manager(void *data, u_int prim, void *arg) {
break;
case MGR_UNREGLAYER | REQUEST:
if (channel == 2) {
inst->down.fdata = &card->dch;
// inst->down.fdata = &card->dch;
if ((skb = create_link_skb(PH_CONTROL | REQUEST,
HW_DEACTIVATE, 0, NULL, 0))) {
if (mISDN_ISAC_l1hw(&inst->down, skb))
if (mISDN_ISAC_l1hw(inst, skb))
dev_kfree_skb(skb);
}
} else {
inst->down.fdata = &card->bch[channel];
// inst->down.fdata = &card->bch[channel];
if ((skb = create_link_skb(MGR_DISCONNECT | REQUEST,
0, 0, NULL, 0))) {
if (isar_down(&inst->down, skb))
if (isar_down(inst, skb))
dev_kfree_skb(skb);
}
}
speedfax.ctrl(inst->up.peer, MGR_DISCONNECT | REQUEST, &inst->up);
// speedfax.ctrl(inst->up.peer, MGR_DISCONNECT | REQUEST, &inst->up);
speedfax.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
break;
case MGR_CLRSTPARA | INDICATION:
@ -669,6 +671,7 @@ speedfax_manager(void *data, u_int prim, void *arg) {
speedfax.refcnt--;
}
break;
#ifdef OBSOLATE
case MGR_CONNECT | REQUEST:
return(mISDN_ConnectIF(inst, arg));
case MGR_SETIF | REQUEST:
@ -680,6 +683,7 @@ speedfax_manager(void *data, u_int prim, void *arg) {
case MGR_DISCONNECT | REQUEST:
case MGR_DISCONNECT | INDICATION:
return(mISDN_DisConnectIF(inst, arg));
#endif
case MGR_LOADFIRM | REQUEST:
{
struct firm {
@ -696,18 +700,18 @@ speedfax_manager(void *data, u_int prim, void *arg) {
break;
case MGR_SETSTACK | CONFIRM:
if ((channel!=2) && (inst->pid.global == 2)) {
inst->down.fdata = &card->bch[channel];
// inst->down.fdata = &card->bch[channel];
if ((skb = create_link_skb(PH_ACTIVATE | REQUEST,
0, 0, NULL, 0))) {
if (isar_down(&inst->down, skb))
if (isar_down(inst, skb))
dev_kfree_skb(skb);
}
if ((inst->pid.protocol[2] == ISDN_PID_L2_B_TRANS) ||
(inst->pid.protocol[2] == ISDN_PID_L2_B_TRANSDTMF))
if_link(&inst->up, DL_ESTABLISH | INDICATION,
mISDN_queue_data(inst, FLG_MSG_UP, DL_ESTABLISH | INDICATION,
0, 0, NULL, 0);
else
if_link(&inst->up, PH_ACTIVATE | INDICATION,
mISDN_queue_data(inst->st, FLG_MSG_UP, PH_ACTIVATE | INDICATION,
0, 0, NULL, 0);
}
break;

View File

@ -28,7 +28,7 @@ get_stack_info(struct sk_buff *skb)
mISDN_head_t *hp;
mISDNstack_t *cst, *st;
stack_info_t *si;
mISDNlayer_t *lay;
int i;
hp = mISDN_HEAD_P(skb);
st = get_stack4id(hp->addr);
@ -46,9 +46,9 @@ get_stack_info(struct sk_buff *skb)
memcpy(&si->pid, &st->pid, sizeof(mISDN_pid_t));
memcpy(&si->para, &st->para, sizeof(mISDN_stPara_t));
si->instcnt = 0;
list_for_each_entry(lay, &st->layerlist, list) {
if (lay->inst) {
si->inst[si->instcnt] = lay->inst->id;
for (i = 0; i <= MAX_LAYER_NR; i++) {
if (st->i_array[i]) {
si->inst[si->instcnt] = st->i_array[i]->id;
si->instcnt++;
}
}
@ -135,6 +135,7 @@ get_stack4id(u_int id)
return(NULL);
}
#ifdef OBSOLATE
mISDNlayer_t *
getlayer4lay(mISDNstack_t *st, int layermask)
{
@ -152,12 +153,48 @@ getlayer4lay(mISDNstack_t *st, int layermask)
}
return(NULL);
}
#endif
static mISDNinstance_t *
get_nextinstance(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);
switch(addr & MSG_DIR_MASK) {
case FLG_MSG_DOWN:
if (addr & FLG_MSG_CLONED) {
} else
layer -= LAYER_ID_INC;
break;
case FLG_MSG_UP:
layer += LAYER_ID_INC;
break;
case MSG_DIRECT:
break;
default: /* broadcast */
int_errtxt("st(%08x) addr(%08x) wrong address", st->id, addr);
return(NULL);
}
if ((layer < 0) || (layer > MAX_LAYER_NR)) {
int_errtxt("st(%08x) addr(%08x) layer %d out of range", st->id, addr, layer);
return(NULL);
}
inst = st->i_array[layer];
/* more checks, refcnt locking */
return(inst);
}
mISDNinstance_t *
get_instance(mISDNstack_t *st, int layer_nr, int protocol)
{
mISDNlayer_t *layer;
mISDNinstance_t *inst=NULL;
int i;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "get_instance st(%p) lnr(%d) prot(%x)\n",
@ -166,29 +203,22 @@ get_instance(mISDNstack_t *st, int layer_nr, int protocol)
int_error();
return(NULL);
}
if ((layer_nr<0) || (layer_nr>MAX_LAYER_NR)) {
if ((layer_nr < 0) || (layer_nr > MAX_LAYER_NR)) {
int_errtxt("lnr %d", layer_nr);
return(NULL);
}
list_for_each_entry(layer, &st->layerlist, list) {
inst = layer->inst;
if (inst) {
for (i = 0; i <= MAX_LAYER_NR; i++) {
if ((inst = st->i_array[i])) {
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "get_instance inst(%p, %x) lm %x/%x prot %x/%x\n",
inst, inst->id, inst->pid.layermask, ISDN_LAYER(layer_nr),
printk(KERN_DEBUG "get_instance inst%d(%p, %x) lm %x/%x prot %x/%x\n",
i,inst, inst->id, inst->pid.layermask, ISDN_LAYER(layer_nr),
inst->pid.protocol[layer_nr], protocol);
if ((inst->pid.layermask & ISDN_LAYER(layer_nr)) &&
(inst->pid.protocol[layer_nr] == protocol))
goto out;
inst = NULL;
}
if (list_empty(&layer->list)) {
int_errtxt("deadloop layer %p", layer);
return(NULL);
return(inst);
}
}
out:
return(inst);
return(NULL);
}
mISDNinstance_t *
@ -202,6 +232,7 @@ get_instance4id(u_int id)
return(NULL);
}
#ifdef OBSOLATE
int
get_layermask(mISDNlayer_t *layer)
{
@ -237,6 +268,114 @@ insertlayer(mISDNstack_t *st, mISDNlayer_t *layer, int layermask)
}
return(0);
}
#endif
int
mISDN_queue_message(mISDNinstance_t *inst, u_int aflag, struct sk_buff *skb)
{
mISDN_head_t *hh = mISDN_HEAD_P(skb);
mISDNstack_t *st = inst->st;
u_int id;
if (aflag && ((aflag & MSG_DIR_MASK) == MSG_DIRECT)) {
id = aflag;
} else {
id = (inst->id & INST_ID_MASK) | aflag;
}
if ((aflag & MSG_DIR_MASK) == FLG_MSG_DOWN) {
if (inst->parent) {
st = inst->parent->st;
id = id | FLG_MSG_CLONED;
}
}
if (!st)
return(-EINVAL);
if (st->id == 0 || test_bit(mISDN_STACK_ABORT, &st->status))
return(-EBUSY);
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);
}
hh->addr = id;
skb_queue_tail(&st->msgq, skb);
wake_up_interruptible(&st->workq);
return(0);
}
static void
do_broadcast(mISDNstack_t *st, struct sk_buff *skb)
{
mISDN_head_t *hh = mISDN_HEAD_P(skb);
/* not implemented yet */
int_errtxt("%s: st(%08x) addr(%08x) prim(%x) dinfo(%x)", __FUNCTION__, st->id, hh->addr, hh->prim, hh->dinfo);
dev_kfree_skb(skb);
}
static int
mISDNStackd(void *data)
{
mISDNstack_t *st = data;
int err = 0;
#ifdef CONFIG_SMP
lock_kernel();
#endif
MAKEDAEMON("mISDNStackd");
sigfillset(&current->blocked);
st->thread = current;
#ifdef CONFIG_SMP
unlock_kernel();
#endif
printk(KERN_DEBUG "mISDNStackd started for id %x\n", st->id);
test_and_clear_bit(mISDN_STACK_INIT, &st->status);
for (;;) {
struct sk_buff *skb;
mISDN_head_t *hh;
while ((skb = skb_dequeue(&st->msgq))) {
mISDNinstance_t *inst;
hh = mISDN_HEAD_P(skb);
if ((hh->addr & MSG_DIR_MASK) == MSG_BROADCAST) {
do_broadcast(st, skb);
continue;
}
inst = get_nextinstance(st, hh->addr);
if (!inst) {
int_errtxt("%s: st(%08x) no instance for id(%08x)", __FUNCTION__, st->id, hh->addr);
dev_kfree_skb(skb);
continue;
}
if (!inst->func) {
int_errtxt("%s: instance(%08x) no function", __FUNCTION__, inst->id);
dev_kfree_skb(skb);
continue;
}
err = inst->func(inst, skb);
if (err) {
int_errtxt("%s: instance(%08x)->function return(%d)", __FUNCTION__, inst->id, err);
dev_kfree_skb(skb);
continue;
}
}
if (test_bit(mISDN_STACK_ABORT, &st->status))
break;
if (st->notify != NULL)
up(st->notify);
interruptible_sleep_on(&st->workq);
}
printk(KERN_DEBUG "mISDNStackd daemon for id %x killed now\n", st->id);
test_and_set_bit(mISDN_STACK_KILLED, &st->status);
discard_queue(&st->msgq);
st->thread = NULL;
if (st->notify != NULL)
up(st->notify);
return(0);
}
mISDNstack_t *
new_stack(mISDNstack_t *master, mISDNinstance_t *inst)
@ -251,8 +390,10 @@ new_stack(mISDNstack_t *master, mISDNinstance_t *inst)
return(NULL);
}
memset(newst, 0, sizeof(mISDNstack_t));
INIT_LIST_HEAD(&newst->layerlist);
INIT_LIST_HEAD(&newst->childlist);
init_waitqueue_head(&newst->workq);
skb_queue_head_init(&newst->msgq);
test_and_set_bit(mISDN_STACK_INIT, &newst->status);
if (!master) {
if (inst && inst->st) {
newst->id = get_free_stackid(inst->st, FLG_CLONE_STACK);
@ -272,6 +413,7 @@ new_stack(mISDNstack_t *master, mISDNinstance_t *inst)
printk(KERN_DEBUG "Stack id %x added\n", newst->id);
if (inst)
inst->st = newst;
kernel_thread(mISDNStackd, (void *)newst, 0);
return(newst);
}
@ -279,24 +421,15 @@ new_stack(mISDNstack_t *master, mISDNinstance_t *inst)
static int
release_layers(mISDNstack_t *st, u_int prim)
{
mISDNinstance_t *inst;
mISDNlayer_t *layer, *nl;
int cnt = 0;
int i;
list_for_each_entry_safe(layer, nl, &st->layerlist, list) {
inst = layer->inst;
if (inst) {
for (i = 0; i <= MAX_LAYER_NR; i++) {
if (st->i_array[i]) {
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: st(%p) inst(%p):%x %s lm(%x)\n",
__FUNCTION__, st, inst, inst->id,
inst->name, inst->pid.layermask);
inst->obj->own_ctrl(inst, prim, NULL);
}
list_del(&layer->list);
kfree(layer);
if (cnt++ > 1000) {
int_errtxt("release_layers endless loop st(%p)", st);
return(-EINVAL);
printk(KERN_DEBUG "%s: st(%p) inst%d(%p):%x %s lm(%x)\n",
__FUNCTION__, st, i, st->i_array[i], st->i_array[i]->id,
st->i_array[i]->name, st->i_array[i]->pid.layermask);
st->i_array[i]->obj->own_ctrl(st->i_array[i], prim, NULL);
}
}
return(0);
@ -306,25 +439,19 @@ int
do_for_all_layers(void *data, u_int prim, void *arg)
{
mISDNstack_t *st = data;
mISDNinstance_t *inst;
mISDNlayer_t *layer, *nl;
int cnt = 0;
int i;
if (!st) {
int_error();
return(-EINVAL);
}
list_for_each_entry_safe(layer, nl, &st->layerlist, list) {
inst = layer->inst;
if (inst) {
for (i = 0; i <= MAX_LAYER_NR; i++) {
if (st->i_array[i]) {
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: st(%p) inst(%p):%x %s prim(%x) arg(%p)\n",
__FUNCTION__, st, inst, inst->id, inst->name, prim, arg);
inst->obj->own_ctrl(inst, prim, arg);
}
if (cnt++ > 1000) {
int_errtxt("do_for_all_layers endless loop st(%p)", st);
return(-EINVAL);
printk(KERN_DEBUG "%s: st(%p) inst%d(%p):%x %s prim(%x) arg(%p)\n",
__FUNCTION__, st, i, st->i_array[i], st->i_array[i]->id,
st->i_array[i]->name, prim, arg);
st->i_array[i]->obj->own_ctrl(st->i_array[i], prim, arg);
}
}
return(0);
@ -367,6 +494,30 @@ change_stack_para(mISDNstack_t *st, u_int prim, mISDN_stPara_t *stpara)
return(do_for_all_layers(st, prim, stpara));
}
static int
delete_stack(mISDNstack_t *st)
{
DECLARE_MUTEX_LOCKED(sem);
int err;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: st(%p)\n", __FUNCTION__, st);
if (st->thread) {
st->notify = &sem;
test_and_set_bit(mISDN_STACK_ABORT, &st->status);
wake_up_interruptible(&st->workq);
down(&sem);
st->notify = NULL;
}
if ((err = release_layers(st, MGR_RELEASE | INDICATION))) {
printk(KERN_WARNING "%s: err(%d)\n", __FUNCTION__, err);
return(err);
}
list_del(&st->list);
kfree(st);
return(0);
}
int
release_stack(mISDNstack_t *st) {
int err;
@ -374,22 +525,16 @@ release_stack(mISDNstack_t *st) {
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: st(%p)\n", __FUNCTION__, st);
list_for_each_entry_safe(cst, nst, &st->childlist, list) {
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: cst(%p)\n", __FUNCTION__, cst);
if ((err = release_layers(cst, MGR_RELEASE | INDICATION))) {
printk(KERN_WARNING "release_stack child err(%d)\n", err);
if ((err = delete_stack(cst))) {
return(err);
}
list_del(&cst->list);
kfree(cst);
}
if ((err = release_layers(st, MGR_RELEASE | INDICATION))) {
printk(KERN_WARNING "release_stack err(%d)\n", err);
if ((err = delete_stack(st)))
return(err);
}
list_del(&st->list);
kfree(st);
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: mISDN_stacklist(%p<-%p->%p)\n", __FUNCTION__,
mISDN_stacklist.prev, &mISDN_stacklist, mISDN_stacklist.next);
@ -397,10 +542,10 @@ release_stack(mISDNstack_t *st) {
}
void
release_stacks(mISDNobject_t *obj) {
mISDNstack_t *st, *tmp;
mISDNlayer_t *layer, *ltmp;
int rel;
release_stacks(mISDNobject_t *obj)
{
mISDNstack_t *st, *tmp;
int rel, i;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: obj(%p) %s\n",
@ -410,11 +555,13 @@ release_stacks(mISDNobject_t *obj) {
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: st(%p)\n",
__FUNCTION__, st);
list_for_each_entry_safe(layer, ltmp, &st->layerlist, list) {
for (i = 0; i <= MAX_LAYER_NR; i++) {
if (!st->i_array[i])
continue;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: layer(%p) inst(%p)\n",
__FUNCTION__, layer, layer->inst);
if (layer->inst && layer->inst->obj == obj)
printk(KERN_DEBUG "%s: inst%d(%p)\n",
__FUNCTION__, i, st->i_array[i]);
if (st->i_array[i]->obj == obj)
rel++;
}
if (rel)
@ -425,7 +572,7 @@ release_stacks(mISDNobject_t *obj) {
obj->name, obj->refcnt);
}
#ifdef OBSOLATE
static void
get_free_instid(mISDNstack_t *st, mISDNinstance_t *inst) {
mISDNinstance_t *il;
@ -441,93 +588,97 @@ get_free_instid(mISDNstack_t *st, mISDNinstance_t *inst) {
inst->id = 0;
return;
}
inst->id += INST_ID_INC;
inst->id += LAYER_ID_INC;
il = list_entry(mISDN_instlist.next, mISDNinstance_t, list);
}
}
}
}
#endif
int
register_layer(mISDNstack_t *st, mISDNinstance_t *inst) {
mISDNlayer_t *layer = NULL;
int refinc = 0;
int idx;
mISDNinstance_t *dup;
if (!inst)
if (!inst || !st)
return(-EINVAL);
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s:st(%p) inst(%p/%p) lmask(%x) id(%x)\n",
__FUNCTION__, st, inst, inst->obj,
inst->pid.layermask, inst->id);
if (inst->id) { /* allready registered */
if (inst->st || !st) {
// if (inst->st || !st) {
int_errtxt("register duplicate %08x %p %p",
inst->id, inst->st, st);
return(-EBUSY);
}
//}
}
if (st) {
if ((layer = getlayer4lay(st, inst->pid.layermask))) {
if (layer->inst) {
int_errtxt("stack %08x has layer %08x",
st->id, layer->inst->id);
return(-EBUSY);
}
} else if (!(layer = kmalloc(sizeof(mISDNlayer_t), GFP_ATOMIC))) {
int_errtxt("no mem for layer %x", inst->pid.layermask);
return(-ENOMEM);
/*
* To simplify registration we assume that our stacks are
* always build with monoton increasing layernumbers from
* bottom (HW,L0) to highest number
*/
// if (st) {
for (idx = 0; idx <= MAX_LAYER_NR; idx++)
if (!st->i_array[idx])
break;
if (idx > MAX_LAYER_NR) {
int_errtxt("stack %08x overflow", st->id);
return(-EXFULL);
}
memset(layer, 0, sizeof(mISDNlayer_t));
insertlayer(st, layer, inst->pid.layermask);
layer->inst = inst;
}
if (!inst->id)
refinc++;
get_free_instid(st, inst);
inst->regcnt++;
st->i_array[idx] = inst;
inst->id = st->id | FLG_INSTANCE | idx;
dup = get_instance4id(inst->id);
if (dup) {
int_errtxt("register duplicate %08x i1(%p) i2(%p) i1->st(%p) i2->st(%p) st(%p)",
inst->id, inst, dup, inst->st, dup->st, st);
inst->regcnt--;
st->i_array[idx] = NULL;
inst->id = 0;
return(-EBUSY);
}
// }
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: inst(%p/%p) id(%x)%s\n", __FUNCTION__,
inst, inst->obj, inst->id, refinc ? " changed" : "");
if (!inst->id) {
int_errtxt("no free inst->id for layer %x", inst->pid.layermask);
if (st && layer) {
list_del(&layer->list);
kfree(layer);
}
return(-EINVAL);
}
printk(KERN_DEBUG "%s: inst(%p/%p) id(%x)\n", __FUNCTION__,
inst, inst->obj, inst->id);
inst->st = st;
if (refinc)
inst->obj->refcnt++;
list_add_tail(&inst->list, &mISDN_instlist);
return(0);
}
int
unregister_instance(mISDNinstance_t *inst) {
mISDNlayer_t *layer;
int err = 0;
int i;
if (!inst)
return(-EINVAL);
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: st(%p) inst(%p):%x lay(%x)\n",
__FUNCTION__, inst->st, inst, inst->id, inst->pid.layermask);
if (inst->st) {
if ((layer = getlayer4lay(inst->st, inst->pid.layermask))) {
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: layer(%p)->inst(%p)\n",
__FUNCTION__, layer, layer->inst);
layer->inst = NULL;
} else {
printk(KERN_WARNING "%s: no layer found\n", __FUNCTION__);
err = -ENODEV;
if (inst->st && inst->id) {
i = inst->id & LAYER_ID_MASK;
if (i > MAX_LAYER_NR) {
int_errtxt("unregister %08x st(%08x) wrong layer", inst->id, inst->st->id);
return(-EINVAL);
}
if (inst->st->i_array[i] == inst) {
inst->regcnt--;
inst->st->i_array[i] = NULL;
} else if (inst->st->i_array[i]) {
int_errtxt("unregister %08x st(%08x) wrong instance %08x",
inst->id, inst->st->id, inst->st->i_array[i]->id);
return(-EINVAL);
} else
printk(KERN_WARNING "unregister %08x st(%08x) not in stack",
inst->id, inst->st->id);
if (inst->st && (inst->st->mgr != inst))
inst->st = NULL;
}
list_del_init(&inst->list);
inst->id = 0;
inst->obj->refcnt--;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: mISDN_instlist(%p<-%p->%p)\n", __FUNCTION__,
mISDN_instlist.prev, &mISDN_instlist, mISDN_instlist.next);
@ -563,7 +714,7 @@ set_stack(mISDNstack_t *st, mISDN_pid_t *pid)
int err;
u_char *pbuf = NULL;
mISDNinstance_t *inst;
mISDNlayer_t *hl, *hln;
// mISDNlayer_t *hl, *hln;
if (!st || !pid) {
int_error();
@ -599,7 +750,8 @@ set_stack(mISDNstack_t *st, mISDN_pid_t *pid)
}
mISDN_RemoveUsedPID(pid, &inst->pid);
}
#ifdef FIXME
list_for_each_entry_safe(hl, hln, &st->layerlist, list) {
if (hl->list.next == &st->layerlist)
break;
@ -618,6 +770,7 @@ set_stack(mISDNstack_t *st, mISDN_pid_t *pid)
hl->inst->obj->own_ctrl(hl->inst, MGR_CONNECT | REQUEST,
hln->inst);
}
#endif
st->mgr->obj->own_ctrl(st->mgr, MGR_SETSTACK |CONFIRM, NULL);
return(0);
}
@ -761,3 +914,5 @@ evaluate_stack_pids(mISDNstack_t *st, mISDN_pid_t *pid)
}
return(0);
}
EXPORT_SYMBOL(mISDN_queue_message);

View File

@ -26,8 +26,8 @@ typedef struct _devicelayer {
mISDNdevice_t *dev;
mISDNinstance_t inst;
mISDNinstance_t *slave;
mISDNif_t s_up;
mISDNif_t s_down;
// mISDNif_t s_up;
// mISDNif_t s_down;
int iaddr;
int lm_st;
u_long Flags;
@ -61,7 +61,7 @@ static char MName[] = "UserDevice";
static int device_debug = 0;
static int from_up_down(mISDNif_t *, struct sk_buff *);
static int from_up_down(mISDNinstance_t *, struct sk_buff *);
// static int from_peer(mISDNif_t *, u_int, int, int, void *);
// static int to_peer(mISDNif_t *, u_int, int, int, void *);
@ -83,16 +83,15 @@ get_mISDNdevice4minor(int minor)
return(NULL);
}
#ifdef FIXME
static int
mISDN_rdata_raw(mISDNif_t *hif, struct sk_buff *skb) {
mISDN_rdata_raw(mISDNinstance_t *inst, struct sk_buff *skb) {
mISDNdevice_t *dev;
mISDN_head_t *hh;
u_long flags;
int retval = 0;
if (!hif || !hif->fdata || !skb)
return(-EINVAL);
dev = hif->fdata;
dev = inst->priv;
hh = mISDN_HEAD_P(skb);
if (hh->prim == (PH_DATA | INDICATION)) {
if (test_bit(FLG_mISDNPORT_OPEN, &dev->rport.Flag)) {
@ -164,6 +163,7 @@ mISDN_rdata_raw(mISDNif_t *hif, struct sk_buff *skb) {
dev_kfree_skb_any(skb);
return(retval);
}
#endif
static int
mISDN_rdata(mISDNdevice_t *dev, struct sk_buff *skb)
@ -210,7 +210,7 @@ static devicelayer_t
// if (device_debug & DEBUG_MGR_FUNC)
// printk(KERN_DEBUG "%s: dl(%p) iaddr:%x\n",
// __FUNCTION__, dl, dl->iaddr);
if ((u_int)dl->iaddr == (IF_IADDRMASK & addr))
if ((u_int)dl->iaddr == (INST_ID_MASK & addr))
return(dl);
}
return(NULL);
@ -327,7 +327,6 @@ static int
create_layer(mISDNdevice_t *dev, struct sk_buff *skb)
{
layer_info_t *linfo;
mISDNlayer_t *layer;
mISDNstack_t *st;
int i, ret;
devicelayer_t *nl;
@ -354,23 +353,16 @@ create_layer(mISDNdevice_t *dev, struct sk_buff *skb)
__FUNCTION__, ret);
return(ret);
}
layer = getlayer4lay(st, linfo->pid.layermask);
if (!layer) {
printk(KERN_WARNING "%s: no layer for lm(%x)\n",
__FUNCTION__, linfo->pid.layermask);
return(-EINVAL);
}
inst = layer->inst;
inst = getlayer4lay(st, linfo->pid.layermask);
if (!inst) {
printk(KERN_WARNING "%s: no inst in layer(%p)\n",
__FUNCTION__, layer);
printk(KERN_WARNING "%s: no inst found\n", __FUNCTION__);
return(-EINVAL);
}
} else if ((layer = getlayer4lay(st, linfo->pid.layermask))) {
} 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(%p)\n",
st->id, linfo->pid.layermask, layer);
"mISDN create_layer st(%x) LM(%x) inst not empty(%08x)\n",
st->id, linfo->pid.layermask, inst->id);
return(-EBUSY);
}
}
@ -399,10 +391,8 @@ create_layer(mISDNdevice_t *dev, struct sk_buff *skb)
st->mgr = &nl->inst;
test_and_set_bit(FLG_MGR_OWNSTACK, &nl->Flags);
}
nl->inst.down.owner = &nl->inst;
nl->inst.up.owner = &nl->inst;
nl->inst.obj = &udev_obj;
nl->inst.data = nl;
nl->inst.privat = nl;
list_add_tail(&nl->list, &dev->layerlist);
nl->inst.obj->ctrl(st, MGR_REGLAYER | INDICATION, &nl->inst);
nl->iaddr = nl->inst.id;
@ -417,41 +407,6 @@ create_layer(mISDNdevice_t *dev, struct sk_buff *skb)
return(8);
}
static int
remove_if(devicelayer_t *dl, int stat) {
mISDNif_t *hif,*phif,*shif;
int err;
if (device_debug & DEBUG_MGR_FUNC)
printk(KERN_DEBUG "%s: dl(%p) stat(%x)\n", __FUNCTION__,
dl, stat);
phif = NULL;
if (stat & IF_UP) {
hif = &dl->inst.up;
shif = &dl->s_up;
if (shif->owner)
phif = &shif->owner->down;
} else if (stat & IF_DOWN) {
hif = &dl->inst.down;
shif = &dl->s_down;
if (shif->owner)
phif = &shif->owner->up;
} else {
printk(KERN_WARNING "%s: stat not UP/DOWN\n", __FUNCTION__);
return(-EINVAL);
}
err = udev_obj.ctrl(hif->peer, MGR_DISCONNECT | REQUEST, hif);
if (phif) {
memcpy(phif, shif, sizeof(mISDNif_t));
memset(shif, 0, sizeof(mISDNif_t));
}
if (hif->predecessor)
hif->predecessor->clone = hif->clone;
if (hif->clone)
hif->clone->predecessor = hif->predecessor;
return(err);
}
static int
del_stack(devicestack_t *ds)
{
@ -491,8 +446,6 @@ del_layer(devicelayer_t *dl)
printk(KERN_DEBUG "%s: iaddr %x inst %s slave %p\n",
__FUNCTION__, dl->iaddr, inst->name, dl->slave);
}
remove_if(dl, IF_UP);
remove_if(dl, IF_DOWN);
if (dl->slave) {
if (dl->slave->obj)
dl->slave->obj->own_ctrl(dl->slave,
@ -514,14 +467,6 @@ del_layer(devicelayer_t *dl)
inst->st->id);
udev_obj.ctrl(inst->st, MGR_CLEARSTACK | REQUEST, NULL);
}
if (inst->up.peer) {
inst->up.peer->obj->ctrl(inst->up.peer,
MGR_DISCONNECT | REQUEST, &inst->up);
}
if (inst->down.peer) {
inst->down.peer->obj->ctrl(inst->down.peer,
MGR_DISCONNECT | REQUEST, &inst->down);
}
dl->iaddr = 0;
list_del(&dl->list);
udev_obj.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL);
@ -559,6 +504,42 @@ 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;
int err;
if (device_debug & DEBUG_MGR_FUNC)
printk(KERN_DEBUG "%s: dl(%p) stat(%x)\n", __FUNCTION__,
dl, stat);
phif = NULL;
if (stat & IF_UP) {
hif = &dl->inst.up;
shif = &dl->s_up;
if (shif->owner)
phif = &shif->owner->down;
} else if (stat & IF_DOWN) {
hif = &dl->inst.down;
shif = &dl->s_down;
if (shif->owner)
phif = &shif->owner->up;
} else {
printk(KERN_WARNING "%s: stat not UP/DOWN\n", __FUNCTION__);
return(-EINVAL);
}
err = udev_obj.ctrl(hif->peer, MGR_DISCONNECT | REQUEST, hif);
if (phif) {
memcpy(phif, shif, sizeof(mISDNif_t));
memset(shif, 0, sizeof(mISDNif_t));
}
if (hif->predecessor)
hif->predecessor->clone = hif->clone;
if (hif->clone)
hif->clone->predecessor = hif->predecessor;
return(err);
}
static int
connect_if_req(mISDNdevice_t *dev, struct sk_buff *skb)
{
@ -765,6 +746,43 @@ del_if_req(mISDNdevice_t *dev, u_int addr)
return(remove_if(dl, addr));
}
static void
get_if_info(struct sk_buff *skb)
{
mISDN_head_t *hp;
mISDNinstance_t *inst;
mISDNif_t *hif;
interface_info_t *ii = (interface_info_t *)skb->data;
hp = mISDN_HEAD_P(skb);
if (!(inst = get_instance4id(hp->addr & IF_ADDRMASK))) {
printk(KERN_WARNING "%s: no instance\n", __FUNCTION__);
hp->len = -ENODEV;
return;
}
if (hp->dinfo == IF_DOWN)
hif = &inst->down;
else if (hp->dinfo == IF_UP)
hif = &inst->up;
else {
printk(KERN_WARNING "%s: wrong interface %x\n",
__FUNCTION__, hp->dinfo);
hp->len = -EINVAL;
return;
}
hp->dinfo = 0;
memset(ii, 0, sizeof(interface_info_t));
if (hif->owner)
ii->owner = hif->owner->id;
if (hif->peer)
ii->peer = hif->peer->id;
ii->extentions = hif->extentions;
ii->stat = hif->stat;
hp->len = sizeof(interface_info_t);
skb_put(skb, hp->len);
}
#endif
static int
new_entity_req(mISDNdevice_t *dev, int *entity)
{
@ -940,7 +958,7 @@ get_status(struct sk_buff *skb)
int err;
hp = mISDN_HEAD_P(skb);
if (!(inst = get_instance4id(hp->addr & IF_ADDRMASK))) {
if (!(inst = get_instance4id(hp->addr & INST_ID_MASK))) {
printk(KERN_WARNING "%s: no instance\n", __FUNCTION__);
err = -ENODEV;
} else {
@ -963,7 +981,7 @@ get_layer_info(struct sk_buff *skb)
layer_info_t *li = (layer_info_t *)skb->data;
hp = mISDN_HEAD_P(skb);
if (!(inst = get_instance4id(hp->addr & IF_ADDRMASK))) {
if (!(inst = get_instance4id(hp->addr & INST_ID_MASK))) {
printk(KERN_WARNING "%s: no instance\n", __FUNCTION__);
hp->len = -ENODEV;
return;
@ -981,47 +999,10 @@ get_layer_info(struct sk_buff *skb)
skb_put(skb, hp->len);
}
static void
get_if_info(struct sk_buff *skb)
{
mISDN_head_t *hp;
mISDNinstance_t *inst;
mISDNif_t *hif;
interface_info_t *ii = (interface_info_t *)skb->data;
hp = mISDN_HEAD_P(skb);
if (!(inst = get_instance4id(hp->addr & IF_ADDRMASK))) {
printk(KERN_WARNING "%s: no instance\n", __FUNCTION__);
hp->len = -ENODEV;
return;
}
if (hp->dinfo == IF_DOWN)
hif = &inst->down;
else if (hp->dinfo == IF_UP)
hif = &inst->up;
else {
printk(KERN_WARNING "%s: wrong interface %x\n",
__FUNCTION__, hp->dinfo);
hp->len = -EINVAL;
return;
}
hp->dinfo = 0;
memset(ii, 0, sizeof(interface_info_t));
if (hif->owner)
ii->owner = hif->owner->id;
if (hif->peer)
ii->peer = hif->peer->id;
ii->extentions = hif->extentions;
ii->stat = hif->stat;
hp->len = sizeof(interface_info_t);
skb_put(skb, hp->len);
}
static int
wdata_frame(mISDNdevice_t *dev, struct sk_buff *skb)
{
mISDN_head_t *hp;
mISDNif_t *hif = NULL;
devicelayer_t *dl;
int err = -ENXIO;
@ -1030,36 +1011,18 @@ wdata_frame(mISDNdevice_t *dev, struct sk_buff *skb)
printk(KERN_DEBUG "%s: addr:%x\n", __FUNCTION__, hp->addr);
if (!(dl=get_devlayer(dev, hp->addr)))
return(err);
if (hp->addr & IF_UP) {
hif = &dl->inst.up;
if (IF_TYPE(hif) != IF_DOWN) {
printk(KERN_WARNING "%s: inst.up no down\n", __FUNCTION__);
hif = NULL;
}
} else if (hp->addr & IF_DOWN) {
hif = &dl->inst.down;
if (IF_TYPE(hif) != IF_UP) {
printk(KERN_WARNING "%s: inst.down no up\n", __FUNCTION__);
hif = NULL;
}
}
if (hif) {
if (device_debug & DEBUG_WDATA)
printk(KERN_DEBUG "%s: pr(%x) di(%x) l(%d)\n",
__FUNCTION__, hp->prim, hp->dinfo, hp->len);
if (hp->len < 0) {
printk(KERN_WARNING "%s: data negativ(%d)\n",
__FUNCTION__, hp->len);
return(-EINVAL);
}
err = hif->func(hif, skb);
if (device_debug & DEBUG_WDATA && err)
printk(KERN_DEBUG "%s: hif->func ret(%x)\n",
__FUNCTION__, err);
} else {
if (device_debug & DEBUG_WDATA)
printk(KERN_DEBUG "mISDN: no matching interface\n");
if (device_debug & DEBUG_WDATA)
printk(KERN_DEBUG "%s: pr(%x) di(%x) l(%d)\n",
__FUNCTION__, hp->prim, hp->dinfo, hp->len);
if (hp->len < 0) {
printk(KERN_WARNING "%s: data negativ(%d)\n",
__FUNCTION__, hp->len);
return(-EINVAL);
}
err = mISDN_queue_message(&dl->inst, hp->addr, skb);
if (device_debug & DEBUG_WDATA && err)
printk(KERN_DEBUG "%s: mISDN_send_message ret(%x)\n",
__FUNCTION__, err);
return(err);
}
@ -1070,7 +1033,7 @@ mISDN_wdata_if(mISDNdevice_t *dev, struct sk_buff *skb)
mISDN_head_t *hp;
mISDNstack_t *st;
devicelayer_t *dl;
mISDNlayer_t *layer;
mISDNinstance_t *inst;
int lay;
int err = 0;
@ -1154,9 +1117,9 @@ mISDN_wdata_if(mISDNdevice_t *dev, struct sk_buff *skb)
hp->len = 0;
lay = ISDN_LAYER(lay);
if ((st = get_stack4id(hp->addr))) {
if ((layer = getlayer4lay(st, lay))) {
if (layer->inst)
hp->dinfo = layer->inst->id;
if ((inst = getlayer4lay(st, lay))) {
if (inst)
hp->dinfo = inst->id;
}
}
}
@ -1190,6 +1153,7 @@ mISDN_wdata_if(mISDNdevice_t *dev, struct sk_buff *skb)
else
hp->len = -ENXIO;
break;
#ifdef OBSOLATE
case (MGR_GETIF | REQUEST):
hp->prim = MGR_GETIF | CONFIRM;
hp->dinfo = 0;
@ -1226,6 +1190,7 @@ mISDN_wdata_if(mISDNdevice_t *dev, struct sk_buff *skb)
hp->prim = MGR_DISCONNECT | CONFIRM;
hp->dinfo = 0;
break;
#endif
case (MGR_NEWENTITY | REQUEST):
hp->prim = MGR_NEWENTITY | CONFIRM;
hp->len = new_entity_req(dev, &hp->dinfo);
@ -1288,7 +1253,7 @@ mISDN_wdata_if(mISDNdevice_t *dev, struct sk_buff *skb)
hp->dinfo = 0;
break;
default:
if (hp->addr & IF_TYPEMASK) {
if (hp->addr & FLG_INSTANCE) {
err = wdata_frame(dev, skb);
if (err) {
if (device_debug & DEBUG_WDATA)
@ -1342,6 +1307,7 @@ init_device(u_int minor) {
return(dev);
}
#ifdef FIXME
mISDNdevice_t *
get_free_rawdevice(void)
{
@ -1366,6 +1332,7 @@ get_free_rawdevice(void)
}
return(NULL);
}
#endif
int
free_device(mISDNdevice_t *dev)
@ -1647,6 +1614,7 @@ do_mISDN_write(struct file *file, const char *buf, size_t count, loff_t * off)
wake_up(&dev->wport.procq);
}
test_and_clear_bit(FLG_mISDNPORT_BUSY, &dev->wport.Flag);
#ifdef FIXME
} else { /* raw device */
skb = alloc_stack_skb(count, PORT_SKB_RESERVE);
if (skb) {
@ -1691,6 +1659,7 @@ do_mISDN_write(struct file *file, const char *buf, size_t count, loff_t * off)
}
test_and_clear_bit(FLG_mISDNPORT_BUSY, &dev->wport.Flag);
spin_unlock_irqrestore(&dev->wport.lock, flags);
#endif
}
return(count - len);
}
@ -1755,18 +1724,16 @@ static struct file_operations mISDN_fops =
};
static int
from_up_down(mISDNif_t *hif, struct sk_buff *skb) {
from_up_down(mISDNinstance_t *inst, struct sk_buff *skb) {
devicelayer_t *dl;
mISDN_head_t *hh;
int retval = -EINVAL;
if (!hif || !hif->fdata || !skb)
return(-EINVAL);
dl = hif->fdata;
dl = inst->privat;
hh = mISDN_HEAD_P(skb);
hh->len = skb->len;
hh->addr = dl->iaddr | IF_TYPE(hif);
hh->addr = dl->iaddr;
if (device_debug & DEBUG_RDATA)
printk(KERN_DEBUG "from_up_down: %x(%x) dinfo:%x len:%d\n",
hh->prim, hh->addr, hh->dinfo, hh->len);
@ -1774,7 +1741,7 @@ from_up_down(mISDNif_t *hif, struct sk_buff *skb) {
return(retval);
}
#ifdef OBSOLATE
static int
set_if(devicelayer_t *dl, u_int prim, mISDNif_t *hif)
{
@ -1783,6 +1750,7 @@ set_if(devicelayer_t *dl, u_int prim, mISDNif_t *hif)
err = mISDN_SetIF(&dl->inst, hif, prim, from_up_down, from_up_down, dl);
return(err);
}
#endif
static int
udev_manager(void *data, u_int prim, void *arg) {
@ -1812,6 +1780,7 @@ udev_manager(void *data, u_int prim, void *arg) {
goto out;
}
switch(prim) {
#ifdef OBSOLATE
case MGR_CONNECT | REQUEST:
err = mISDN_ConnectIF(inst, arg);
break;
@ -1823,6 +1792,7 @@ udev_manager(void *data, u_int prim, void *arg) {
case MGR_DISCONNECT | INDICATION:
err = mISDN_DisConnectIF(inst, arg);
break;
#endif
case MGR_RELEASE | INDICATION:
if (device_debug & DEBUG_MGR_FUNC)
printk(KERN_DEBUG "release_dev id %x\n",

View File

@ -851,18 +851,13 @@ dte_dl_data_ind(x25_l3_t *l3, struct sk_buff *skb)
}
static int
dte_from_down(mISDNif_t *hif, struct sk_buff *skb)
dte_from_down(mISDNinstance_t *inst, struct sk_buff *skb)
{
x25_l3_t *l3;
mISDN_head_t *hh;
int ret = -EINVAL;
if (!hif || !hif->fdata || !skb)
return(ret);
l3 = hif->fdata;
if (!l3->inst.up.func) {
return(-ENXIO);
}
l3 = inst->privat;
hh = mISDN_HEAD_P(skb);
if (l3->debug)
printk(KERN_DEBUG "%s: prim(%x) dinfo(%x)\n", __FUNCTION__, hh->prim, hh->dinfo);
@ -1049,7 +1044,7 @@ new_l3(mISDNstack_t *st, mISDN_pid_t *pid) {
}
static int
dte_from_up(mISDNif_t *hif, struct sk_buff *skb)
dte_from_up(mISDNinstance_t *inst, struct sk_buff *skb)
{
x25_l3_t *l3;
x25_channel_t *l3c;
@ -1058,12 +1053,7 @@ dte_from_up(mISDNif_t *hif, struct sk_buff *skb)
__u16 info = 0;
int err = 0;
if (!hif || !hif->fdata || !skb)
return(-EINVAL);
l3 = hif->fdata;
if (!l3->inst.down.func) {
return(-ENXIO);
}
l3 = inst->privat;
hh = mISDN_HEAD_P(skb);
if (l3->debug)
printk(KERN_DEBUG "%s: prim(%x) dinfo(%x) len(%d)\n", __FUNCTION__, hh->prim, hh->dinfo, skb->len);
@ -1287,6 +1277,7 @@ dte_manager(void *data, u_int prim, void *arg) {
case MGR_CLRSTPARA | INDICATION:
case MGR_CLONELAYER | REQUEST:
break;
#ifdef OBSOLATE
case MGR_CONNECT | REQUEST:
return(mISDN_ConnectIF(inst, arg));
case MGR_SETIF | REQUEST:
@ -1295,6 +1286,7 @@ dte_manager(void *data, u_int prim, void *arg) {
case MGR_DISCONNECT | REQUEST:
case MGR_DISCONNECT | INDICATION:
return(mISDN_DisConnectIF(inst, arg));
#endif
case MGR_UNREGLAYER | REQUEST:
case MGR_RELEASE | INDICATION:
if (debug & DEBUG_L3X25_MGR)

View File

@ -378,7 +378,7 @@ X25_confirmed(x25_channel_t *chan)
i = cq->MsgId;
/* free entry */
cq->PktId = 0;
ret = if_newhead(&chan->l3->inst.up, CAPI_DATA_B3_CONF, i, skb);
ret = mISDN_queueup_newhead(&chan->l3->inst, 0, CAPI_DATA_B3_CONF, i, skb);
if (ret) {
printk(KERN_WARNING "%s: up error %d\n", __FUNCTION__, ret);
dev_kfree_skb(skb);
@ -453,7 +453,7 @@ X25_receive_data(x25_channel_t *chan, int ps, int flag, struct sk_buff *skb)
capimsg_setu16(nskb->data, 10, i);
capimsg_setu16(nskb->data, 12, flag);
if (if_newhead(&chan->l3->inst.up, CAPI_DATA_B3_IND, 0, nskb)) {
if (mISDN_queueup_newhead(&chan->l3->inst, 0, CAPI_DATA_B3_IND, 0, nskb)) {
chan->recv_handles[i] = 0;
return(X25_ERRCODE_DISCARD);
}
@ -560,6 +560,7 @@ X25_release_l3(x25_l3_t *l3) {
mISDNinstance_t *inst = &l3->inst;
x25_channel_t *ch, *nch;
#ifdef OBSOLATE
if (inst->up.peer) {
inst->up.peer->obj->ctrl(inst->up.peer,
MGR_DISCONNECT | REQUEST, &inst->up);
@ -568,6 +569,7 @@ X25_release_l3(x25_l3_t *l3) {
inst->down.peer->obj->ctrl(inst->down.peer,
MGR_DISCONNECT | REQUEST, &inst->down);
}
#endif
if (inst->obj) {
list_del_init(&l3->list);
}
@ -853,9 +855,7 @@ X25sendL3frame(x25_channel_t *l3c, x25_l3_t *l3, u_char pt, int len, void *arg)
mISDN_sethead(DL_DATA_REQ, X25_next_id(l3), skb);
if (l3->l2l3m.state == ST_LL_ESTAB) {
mISDNif_t *down = &l3->inst.down;
ret = down->func(down, skb);
ret = mISDN_queue_message(&l3->inst, FLG_MSG_DOWN, skb);
if (ret) {
dev_kfree_skb(skb);
}
@ -869,15 +869,13 @@ X25sendL3frame(x25_channel_t *l3c, x25_l3_t *l3, u_char pt, int len, void *arg)
int
X25_l3down(x25_l3_t *l3, u_int prim, u_int dinfo, struct sk_buff *skb)
{
mISDNif_t *down = &l3->inst.down;
int ret;
if (!skb) {
if (!(skb = alloc_stack_skb(0, l3->down_headerlen)))
return(-ENOMEM);
}
mISDN_sethead(prim, dinfo, skb);
ret = down->func(down, skb);
ret = mISDN_queuedown_newhead(&l3->inst, 0, prim, dinfo, skb);
if (ret) {
dev_kfree_skb(skb);
}
@ -951,7 +949,7 @@ X25sendL4skb(x25_channel_t *l3c, x25_l3_t *l3, __u32 addr, int prim, int dinfo,
capimsg_setu32(skb->data, 0, l3c->ncci);
else
capimsg_setu32(skb->data, 0, addr);
return(if_newhead(&l3->inst.up, prim, dinfo, skb));
return(mISDN_queueup_newhead(&l3->inst, 0, prim, dinfo, skb));
}
int
@ -991,7 +989,7 @@ X25sendL4frame(x25_channel_t *l3c, x25_l3_t *l3, int prim, int flags, int len, v
dev_kfree_skb(skb);
return(-EINVAL);
}
ret = if_newhead(&l3->inst.up, prim, 0, skb);
ret = mISDN_queueup_newhead(&l3->inst, 0, prim, 0, skb);
if (ret) {
printk(KERN_WARNING "%s: up error %d\n", __FUNCTION__, ret);
dev_kfree_skb(skb);

View File

@ -29,7 +29,7 @@
* - changed if any interface is extended but backwards compatible
*
*/
#define MISDN_MAJOR_VERSION 1
#define MISDN_MAJOR_VERSION 2
#define MISDN_MINOR_VERSION 0
#define MISDN_VERSION ((MISDN_MAJOR_VERSION<<16) | MISDN_MINOR_VERSION)
@ -66,12 +66,12 @@
#define MGR_NEWLAYER 0x0f2300
#define MGR_DELLAYER 0x0f2400
#define MGR_CLONELAYER 0x0f2500
#define MGR_GETIF 0x0f3100
#define MGR_CONNECT 0x0f3200
//#define MGR_GETIF 0x0f3100
//#define MGR_CONNECT 0x0f3200
#define MGR_DISCONNECT 0x0f3300
#define MGR_SETIF 0x0f3400
#define MGR_ADDIF 0x0f3500
#define MGR_QUEUEIF 0x0f3600
//#define MGR_SETIF 0x0f3400
//#define MGR_ADDIF 0x0f3500
//#define MGR_QUEUEIF 0x0f3600
#define MGR_CTRLREADY 0x0f4100
#define MGR_RELEASE 0x0f4500
#define MGR_GETDEVICE 0x0f5100
@ -418,6 +418,7 @@
#define LAYER_OUTRANGE(layer) ((layer<0) || (layer>MAX_LAYER_NR))
#define mISDN_MAX_IDLEN 16
#ifdef OBSOLATE
#define IF_NOACTIV 0x00000000
#define IF_DOWN 0x01000000
#define IF_UP 0x02000000
@ -432,18 +433,50 @@
#define IF_INSTMASK 0x400F0000
#define IF_LAYERMASK 0x00F00000
#define IF_TYPE(i) ((i)->stat & IF_TYPEMASK)
#define CHILD_ID_INC 0x00000100
#define CHILD_ID_MAX 0x1000FF00
#define CLONE_ID_INC 0x00000100
#define CLONE_ID_MAX 0x2000FF00
#define INST_ID_INC 0x00010000
#define INST_ID_MAX 0x400F0000
#endif
/*
* general ID layout for instance and stack id's
* 3322 2222 2222 1111 1111 1100 0000 0000
* 1098 7654 3210 9876 5432 1098 7654 3210
* FFFF FFFF CCCC CCCC SSSS SSSS RRRR LLLL
*
* L (bit 03-00) Layer ID
* R (bit 07-04) reserved (0)
* S (bit 15-08) Stack ID/controller number
* C (bit 23-16) Child/Clone ID
* F (bit 31-24) Flags as defined below
*
*/
#define FLG_MSG_DOWN 0x01000000
#define FLG_MSG_UP 0x02000000
#define FLG_MSG_CLONED 0x04000000
#define FLG_CHILD_STACK 0x10000000
#define FLG_CLONE_STACK 0x20000000
#define FLG_INSTANCE 0x40000000
#define FLG_MSG_TAGGED 0x80000000
#define MSG_DIR_MASK 0x03000000
#define MSG_BROADCAST 0x03000000
#define MSG_DIRECT 0x00000000
#define CHILD_ID_INC 0x00010000
#define CHILD_ID_MAX 0x00FF0000
#define CHILD_ID_MASK 0x00FF0000
#define CLONE_ID_INC 0x00010000
#define CLONE_ID_MAX 0x00FF0000
#define CLONE_ID_MASK 0x00FF0000
#define STACK_ID_INC 0x00000100
#define STACK_ID_MAX 0x0000FF00
#define STACK_ID_MASK 0x30FFFF00
#define MASTER_ID_MASK 0x0000FF00
#define LAYER_ID_INC 0x00000001
#define LAYER_ID_MAX MAX_LAYER_NR
#define LAYER_ID_MASK 0x0000000F
#define INST_ID_MASK 0x70FFFFFF
#define DUMMY_CR_FLAG 0x7FFFFF00
#define CONTROLER_MASK 0x000000FF
// #define CONTROLER_MASK 0x0000FF
/* stack channel values */
#define CHANNEL_NUMBER 0x000000FF
@ -466,6 +499,11 @@
#define EXT_IF_CREATE 0x00040000
#define EXT_IF_SPLIT 0x00080000
/* stack status flag (bit position) */
#define mISDN_STACK_INIT 0
#define mISDN_STACK_STOPPED 1
#define mISDN_STACK_ABORT 2
#define mISDN_STACK_KILLED 3
/* special packet type */
#define PACKET_NOACK 250
@ -617,13 +655,14 @@ typedef struct _Q931_info {
typedef struct _mISDNobject mISDNobject_t;
typedef struct _mISDNinstance mISDNinstance_t;
typedef struct _mISDNlayer mISDNlayer_t;
// typedef struct _mISDNlayer mISDNlayer_t;
typedef struct _mISDNstack mISDNstack_t;
typedef struct _mISDNport mISDNport_t;
typedef struct _mISDNdevice mISDNdevice_t;
typedef struct _mISDNif mISDNif_t;
//typedef struct _mISDNif mISDNif_t;
typedef int (ctrl_func_t)(void *, u_int, void *);
typedef int (if_func_t)(struct _mISDNif *, struct sk_buff *);
//typedef int (if_func_t)(struct _mISDNif *, struct sk_buff *);
typedef int (if_func_t)(mISDNinstance_t *, struct sk_buff *);
typedef int (lock_func_t)(void *, int);
typedef void (unlock_func_t)(void *);
@ -659,6 +698,7 @@ struct _mISDNobject {
struct module *owner;
};
#if 0
/* the interface between two mISDNinstances */
struct _mISDNif {
if_func_t *func;
@ -671,6 +711,7 @@ struct _mISDNif {
mISDNinstance_t *owner;
mISDNinstance_t *peer;
};
#endif
/* a instance of a mISDNobject */
struct _mISDNinstance {
@ -678,16 +719,20 @@ struct _mISDNinstance {
char name[mISDN_MAX_IDLEN];
int extentions;
u_int id;
int regcnt;
mISDN_pid_t pid;
mISDNstack_t *st;
mISDNobject_t *obj;
void *data;
mISDNif_t up;
mISDNif_t down;
void *privat;
mISDNinstance_t *clone;
mISDNinstance_t *parent;
if_func_t *func;
// mISDNif_t up;
// mISDNif_t down;
lock_func_t *lock;
unlock_func_t *unlock;
};
#if 0
/* a list of parallel (horizontal) mISDNinstances in the same layer
* normally here is only one instance per layer only if the information
* will be splitted here are more instances */
@ -695,7 +740,7 @@ struct _mISDNlayer {
struct list_head list;
mISDNinstance_t *inst;
};
#endif
/* the STACK; a (vertical) chain of layers */
struct _mISDNstack {
@ -704,7 +749,13 @@ struct _mISDNstack {
u_int extentions;
mISDN_pid_t pid;
mISDN_stPara_t para;
struct list_head layerlist;
u_long status;
struct task_struct *thread;
struct semaphore *notify;
wait_queue_head_t workq;
struct sk_buff_head msgq;
mISDNinstance_t *i_array[MAX_LAYER_NR + 1];
// struct list_head layerlist;
mISDNinstance_t *mgr;
struct list_head childlist;
};
@ -713,7 +764,7 @@ struct _mISDNstack {
struct _mISDNport {
wait_queue_head_t procq;
spinlock_t lock;
mISDNif_t pif;
// mISDNif_t pif;
u_long Flag;
struct sk_buff_head queue;
u_int maxqlen;
@ -735,9 +786,11 @@ struct _mISDNdevice {
/* common helper functions */
extern int mISDN_bprotocol2pid(void *, mISDN_pid_t *);
extern int mISDN_SetIF(mISDNinstance_t *, mISDNif_t *, u_int, void *, void *, void *);
extern int mISDN_ConnectIF(mISDNinstance_t *, mISDNinstance_t *);
extern int mISDN_DisConnectIF(mISDNinstance_t *, mISDNif_t *);
// extern int mISDN_SetIF(mISDNinstance_t *, mISDNif_t *, u_int, void *, void *, void *);
// extern int mISDN_ConnectIF(mISDNinstance_t *, mISDNinstance_t *);
// extern int mISDN_DisConnectIF(mISDNinstance_t *, mISDNif_t *);
extern int mISDN_queue_message(mISDNinstance_t *, u_int, struct sk_buff *);
/* global register/unregister functions */