Compare commits

...

2 Commits

Author SHA1 Message Date
Karsten Keil 2adfad64db add missin defines 2006-04-30 22:13:40 +00:00
Karsten Keil 2006e7819e create instance 2006-04-30 17:27:03 +00:00
27 changed files with 789 additions and 230 deletions

View File

@ -22,7 +22,7 @@ CONFIGS+=CONFIG_MISDN_DRV=m CONFIG_MISDN_DSP=m
CONFIGS+=CONFIG_MISDN_HFCMULTI=m
CONFIGS+=CONFIG_MISDN_HFCPCI=m
CONFIGS+=CONFIG_MISDN_HFCUSB=m
CONFIGS+=CONFIG_MISDN_XHFC=m
#CONFIGS+=CONFIG_MISDN_XHFC=m
CONFIGS+=CONFIG_MISDN_HFCMINI=m
CONFIGS+=CONFIG_MISDN_W6692=m
CONFIGS+=CONFIG_MISDN_SPEEDFAX=m

View File

@ -1559,86 +1559,166 @@ PL_l3l4mux(mISDNinstance_t *inst, struct sk_buff *skb)
static int
AppPlciLinkUp(AppPlci_t *aplci)
{
mISDN_pid_t pid;
mISDN_stPara_t stpara;
int retval;
struct sk_buff *skb;
mISDN_pid_t *pid;
int len, *ch;
if (aplci->channel == -1) {/* no valid channel set */
int_error();
return(-EINVAL);
}
memset(&pid, 0, sizeof(mISDN_pid_t));
pid.layermask = ISDN_LAYER(1) | ISDN_LAYER(2) | ISDN_LAYER(3) |
ISDN_LAYER(4);
if (test_bit(PLCI_STATE_OUTGOING, &aplci->plci->state))
pid.global = 1; // DTE, orginate
else
pid.global = 2; // DCE, answer
if (aplci->link) {
capidebug(CAPI_DBG_PLCI, "AppPlciLinkUp link already up");
return(0);
}
if (aplci->linkid) {
capidebug(CAPI_DBG_PLCI, "AppPlciLinkUp link already requested id(%x)");
return(0);
}
if (aplci->Bprotocol.B1 > 23) {
int_errtxt("wrong B1 prot %x", aplci->Bprotocol.B1);
return(0x3001);
}
pid.protocol[1] = (1 << aplci->Bprotocol.B1) |
ISDN_PID_LAYER(1) | ISDN_PID_BCHANNEL_BIT;
if (aplci->Bprotocol.B1cfg[0]) {
pid.param[1] = &aplci->Bprotocol.B1cfg[0];
pid.maxplen += aplci->Bprotocol.B1cfg[0];
}
if (aplci->Bprotocol.B2 > 23) {
int_errtxt("wrong B2 prot %x", aplci->Bprotocol.B2);
return(0x3002);
}
pid.protocol[2] = (1 << aplci->Bprotocol.B2) |
ISDN_PID_LAYER(2) | ISDN_PID_BCHANNEL_BIT;
if (aplci->Bprotocol.B2cfg[0]) {
pid.param[2] = &aplci->Bprotocol.B2cfg[0];
pid.maxplen += aplci->Bprotocol.B2cfg[0];
}
/* handle DTMF TODO */
if ((pid.protocol[2] == ISDN_PID_L2_B_TRANS) &&
(pid.protocol[1] == ISDN_PID_L1_B_64TRANS))
pid.protocol[2] = ISDN_PID_L2_B_TRANSDTMF;
if (aplci->Bprotocol.B3 > 23) {
int_errtxt("wrong B3 prot %x", aplci->Bprotocol.B3);
return(0x3003);
}
pid.protocol[3] = (1 << aplci->Bprotocol.B3) |
len = aplci->Bprotocol.B1cfg[0];
len += aplci->Bprotocol.B2cfg[0];
len += aplci->Bprotocol.B3cfg[0];
if (!(skb = alloc_skb(len + sizeof(int) + sizeof(mISDN_pid_t), GFP_ATOMIC))) {
int_errtxt("no skb size(%d+%d+%d)", len, sizeof(int), sizeof(mISDN_pid_t));
return(-ENOMEM);
}
ch = (int *)skb_put(skb, sizeof(int));
*ch = aplci->channel;
pid = (mISDN_pid_t *)skb_put(skb, sizeof(mISDN_pid_t));
memset(pid, 0, sizeof(mISDN_pid_t));
pid->maxplen = len;
pid->layermask = ISDN_LAYER(1) | ISDN_LAYER(2) | ISDN_LAYER(3) |
ISDN_LAYER(4);
if (test_bit(PLCI_STATE_OUTGOING, &aplci->plci->state))
pid->global = 1; // DTE, orginate
else
pid->global = 2; // DCE, answer
pid->protocol[1] = (1 << aplci->Bprotocol.B1) |
ISDN_PID_LAYER(1) | ISDN_PID_BCHANNEL_BIT;
if (aplci->Bprotocol.B1cfg[0]) {
pid->param[1] = skb_put(skb, aplci->Bprotocol.B1cfg[0]);
memcpy(pid->param[1], &aplci->Bprotocol.B1cfg[0], aplci->Bprotocol.B1cfg[0]);
}
pid->protocol[2] = (1 << aplci->Bprotocol.B2) |
ISDN_PID_LAYER(2) | ISDN_PID_BCHANNEL_BIT;
if (aplci->Bprotocol.B2cfg[0]) {
pid->param[2] = skb_put(skb, aplci->Bprotocol.B2cfg[0]);
memcpy(pid->param[2], &aplci->Bprotocol.B2cfg[0], aplci->Bprotocol.B2cfg[0]);
}
/* handle DTMF TODO */
if ((pid->protocol[2] == ISDN_PID_L2_B_TRANS) &&
(pid->protocol[1] == ISDN_PID_L1_B_64TRANS))
pid->protocol[2] = ISDN_PID_L2_B_TRANSDTMF;
pid->protocol[3] = (1 << aplci->Bprotocol.B3) |
ISDN_PID_LAYER(3) | ISDN_PID_BCHANNEL_BIT;
if (aplci->Bprotocol.B3cfg[0]) {
pid.param[3] = &aplci->Bprotocol.B3cfg[0];
pid.maxplen += aplci->Bprotocol.B3cfg[0];
pid->param[3] = skb_put(skb, aplci->Bprotocol.B3cfg[0]);
memcpy(pid->param[3], &aplci->Bprotocol.B3cfg[0], aplci->Bprotocol.B3cfg[0]);
}
capidebug(CAPI_DBG_PLCI, "AppPlciLinkUp B1(%x) B2(%x) B3(%x) global(%d) ch(%x)",
pid.protocol[1], pid.protocol[2], pid.protocol[3], pid.global,
aplci->channel);
pid->protocol[1], pid->protocol[2], pid->protocol[3], pid->global, *ch);
capidebug(CAPI_DBG_PLCI, "AppPlciLinkUp ch(%d) aplci->contr->linklist(%p)",
aplci->channel & 3, aplci->contr->linklist);
pid.protocol[4] = ISDN_PID_L4_B_CAPI20;
aplci->link = ControllerSelChannel(aplci->contr, aplci->channel);
if (!aplci->link) {
pid->protocol[4] = ISDN_PID_L4_B_CAPI20;
aplci->linkid = ControllerNextId(aplci->contr);
capidebug(CAPI_DBG_PLCI, "AppPlciLinkUp request channel id(%x)", aplci->linkid);
mISDN_sethead(MGR_SELCHANNEL | REQUEST, aplci->linkid, skb);
len = mISDN_queue_message(&aplci->contr->inst, FLG_MSG_TARGET | aplci->contr->inst.id, skb);
if (len) {
int_error();
return(-EBUSY);
dev_kfree_skb(skb);
}
capidebug(CAPI_DBG_NCCI, "AppPlciLinkUp aplci->link(%p)", aplci->link);
return(len);
}
static void
AppPlciSetLink(AppPlci_t *aplci, PLInst_t *link)
{
int retval;
struct sk_buff *skb;
mISDN_pid_t *pid;
mISDN_stPara_t stpara;
int len;
aplci->link = link;
aplci->linkid = 0;
if (!link) {
int_error();
#warning TODO no link handling
return;
}
capidebug(CAPI_DBG_NCCI, "AppPlciSetLink aplci->link(%p)", aplci->link);
len = aplci->Bprotocol.B1cfg[0];
len += aplci->Bprotocol.B2cfg[0];
len += aplci->Bprotocol.B3cfg[0];
if (!(skb = alloc_skb(len + sizeof(mISDN_pid_t), GFP_ATOMIC))) {
int_errtxt("no skb size(%d+%d)", len, sizeof(mISDN_pid_t));
return;
}
pid = (mISDN_pid_t *)skb_put(skb, sizeof(mISDN_pid_t));
memset(pid, 0, sizeof(mISDN_pid_t));
pid->maxplen = len;
pid->layermask = ISDN_LAYER(1) | ISDN_LAYER(2) | ISDN_LAYER(3) |
ISDN_LAYER(4);
if (test_bit(PLCI_STATE_OUTGOING, &aplci->plci->state))
pid->global = 1; // DTE, orginate
else
pid->global = 2; // DCE, answer
pid->protocol[1] = (1 << aplci->Bprotocol.B1) |
ISDN_PID_LAYER(1) | ISDN_PID_BCHANNEL_BIT;
if (aplci->Bprotocol.B1cfg[0]) {
pid->param[1] = skb_put(skb, aplci->Bprotocol.B1cfg[0]);
memcpy(pid->param[1], &aplci->Bprotocol.B1cfg[0], aplci->Bprotocol.B1cfg[0]);
}
pid->protocol[2] = (1 << aplci->Bprotocol.B2) |
ISDN_PID_LAYER(2) | ISDN_PID_BCHANNEL_BIT;
if (aplci->Bprotocol.B2cfg[0]) {
pid->param[2] = skb_put(skb, aplci->Bprotocol.B2cfg[0]);
memcpy(pid->param[2], &aplci->Bprotocol.B2cfg[0], aplci->Bprotocol.B2cfg[0]);
}
/* handle DTMF TODO */
if ((pid->protocol[2] == ISDN_PID_L2_B_TRANS) &&
(pid->protocol[1] == ISDN_PID_L1_B_64TRANS))
pid->protocol[2] = ISDN_PID_L2_B_TRANSDTMF;
pid->protocol[3] = (1 << aplci->Bprotocol.B3) |
ISDN_PID_LAYER(3) | ISDN_PID_BCHANNEL_BIT;
if (aplci->Bprotocol.B3cfg[0]) {
pid->param[3] = skb_put(skb, aplci->Bprotocol.B3cfg[0]);
memcpy(pid->param[3], &aplci->Bprotocol.B3cfg[0], aplci->Bprotocol.B3cfg[0]);
}
pid->protocol[4] = ISDN_PID_L4_B_CAPI20;
memset(&aplci->link->inst.pid, 0, sizeof(mISDN_pid_t));
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) {
aplci->link->inst.pid.protocol[3] = ISDN_PID_L3_B_TRANS;
aplci->link->inst.pid.layermask |= ISDN_LAYER(3);
}
if (aplci->link->inst.function)
int_errtxt("id(%08x) overwrite function (%p)", aplci->link->inst.id, aplci->link->inst.function);
if (aplci->Bprotocol.B3 == 0) // transparent
if (aplci->Bprotocol.B3 == 0) { // transparent
aplci->link->inst.pid.protocol[3] = ISDN_PID_L3_B_TRANS;
aplci->link->inst.pid.layermask |= ISDN_LAYER(3);
aplci->link->inst.function = PL_l3l4;
else
} else
aplci->link->inst.function = PL_l3l4mux;
retval = mISDN_ctrl(aplci->link->st, MGR_ADDLAYER | REQUEST, &aplci->link->inst);
if (retval) {
printk(KERN_WARNING "%s MGR_ADDLAYER | REQUEST ret(%d)\n",
__FUNCTION__, retval);
return(retval);
return;
}
stpara.maxdatalen = aplci->appl->reg_params.datablklen;
stpara.up_headerlen = CAPI_B3_DATA_IND_HEADER_SIZE;
@ -1649,13 +1729,12 @@ AppPlciLinkUp(AppPlci_t *aplci)
printk(KERN_WARNING "%s MGR_SETSTACK | REQUEST ret(%d)\n",
__FUNCTION__, retval);
}
retval = mISDN_ctrl(aplci->link->st, MGR_SETSTACK | REQUEST, &pid);
mISDN_sethead(MGR_SETSTACK | REQUEST, 0, skb);
retval = mISDN_queue_message(&aplci->link->inst, FLG_MSG_TARGET | aplci->link->inst.id, skb);
if (retval) {
printk(KERN_WARNING "%s MGR_SETSTACK | REQUEST ret(%d)\n",
__FUNCTION__, retval);
return(retval);
int_error();
dev_kfree_skb(skb);
}
return(0);
}
static int
@ -1934,6 +2013,9 @@ AppPlci_l3l4(AppPlci_t *aplci, int pr, void *arg)
/* TOUCH TONE */
mISDN_FsmEvent(&aplci->plci_m, EV_PH_CONTROL_IND, arg);
break;
case MGR_SELCHANNEL | CONFIRM:
AppPlciSetLink(aplci, arg);
break;
default:
AppPlciDebug(aplci, CAPI_DBG_WARN,
"%s: pr 0x%x not handled", __FUNCTION__, pr);

View File

@ -1060,6 +1060,35 @@ release_card(fritzpnppci *card)
kfree(card);
}
static int
fritz_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
fritzpnppci *card;
mISDNinstance_t *inst = NULL;
u_long flags;
spin_lock_irqsave(&fritz.lock, flags);
list_for_each_entry(card, &fritz.ilist, list) {
if (card->dch.inst.st == st) {
inst = &card->dch.inst;
break;
}
if (card->bch[0].inst.st == st) {
inst = &card->bch[0].inst;
break;
}
if (card->bch[1].inst.st == st) {
inst = &card->bch[1].inst;
break;
}
}
spin_unlock_irqrestore(&fritz.lock, flags);
if (!inst)
return(-EINVAL);
return(mISDN_ctrl(st, MGR_REGLAYER | REQUEST, inst));
}
#ifdef OBSOLETE
static int
fritz_manager(void *data, u_int prim, void *arg) {
fritzpnppci *card;
@ -1159,7 +1188,7 @@ fritz_manager(void *data, u_int prim, void *arg) {
}
return(0);
}
#endif
static int __devinit setup_instance(fritzpnppci *card)
{
int i, err;
@ -1404,7 +1433,7 @@ static int __init Fritz_init(void)
spin_lock_init(&fritz.lock);
INIT_LIST_HEAD(&fritz.ilist);
fritz.name = FritzName;
fritz.own_ctrl = fritz_manager;
fritz.getinst = fritz_instance;
fritz.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0;
fritz.BPROTO.protocol[1] = ISDN_PID_L1_B_64TRANS |
ISDN_PID_L1_B_64HDLC;

View File

@ -305,6 +305,42 @@ static int CapiNew(void)
return 0;
}
static int
capi20_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
Controller_t *ctrl;
PLInst_t *plink = NULL;
mISDNinstance_t *inst = NULL;
u_long flags;
int ret;
spin_lock_irqsave(&capi_obj.lock, flags);
list_for_each_entry(ctrl, &capi_obj.ilist, list) {
if (ctrl->inst.st == st) {
inst = &ctrl->inst;
break;
}
list_for_each_entry(plink, &ctrl->linklist, list) {
if (plink->inst.st == st) {
inst = &plink->inst;
break;
}
}
if (inst)
break;
}
spin_unlock_irqrestore(&capi_obj.lock, flags);
if (!inst) {
ctrl = NULL;
ret = ControllerConstr(&ctrl, st, pid, &capi_obj);
if (ret == 0)
ctrl->debug = debug;
} else
ret = mISDN_ctrl(st, MGR_REGLAYER | REQUEST, inst);
return(ret);
}
#ifdef OBSOLETE
static int
capi20_manager(void *data, u_int prim, void *arg) {
mISDNinstance_t *inst = data;
@ -391,6 +427,7 @@ capi20_manager(void *data, u_int prim, void *arg) {
}
return(0);
}
#endif
int Capi20Init(void)
{
@ -404,7 +441,7 @@ int Capi20Init(void)
capi_obj.DPROTO.protocol[4] = ISDN_PID_L4_CAPI20;
capi_obj.BPROTO.protocol[4] = ISDN_PID_L4_B_CAPI20;
capi_obj.BPROTO.protocol[3] = ISDN_PID_L3_B_TRANS;
capi_obj.own_ctrl = capi20_manager;
capi_obj.getinst = capi20_instance;
spin_lock_init(&capi_obj.lock);
INIT_LIST_HEAD(&capi_obj.ilist);
if ((err = CapiNew()))

View File

@ -545,6 +545,43 @@ SSProcess_t
return(sp);
}
static int
ControllerSelChannel(Controller_t *contr, int dinfo, struct sk_buff *skb)
{
PLInst_t *plink = NULL;
int *id;
Plci_t *plci = contr->plcis;
AppPlci_t *aplci;
struct list_head *item, *next;
int i;
for (i = 0; i < contr->maxplci; i++) {
if (test_bit(PLCI_STATE_ACTIV, &plci->state)) {
list_for_each_safe(item, next, &plci->AppPlcis) {
aplci = (AppPlci_t *)item;
if (aplci->linkid == dinfo)
goto found;
}
}
plci++;
}
int_errtxt("no linkid(%x) match", dinfo);
return(-EINVAL);
found:
if (skb->len && !list_empty(&contr->linklist)) {
id = (int *)skb->data;
list_for_each_entry(plink, &contr->linklist, list) {
if (plink->st && plink->st->id == *id) {
AppPlci_l3l4(aplci, MGR_SELCHANNEL | CONFIRM, plink);
return(0);
}
}
}
int_errtxt("link not found");
AppPlci_l3l4(aplci, MGR_SELCHANNEL | CONFIRM, NULL);
return(-EBUSY);
}
static int
Controller_function(mISDNinstance_t *inst, struct sk_buff *skb)
{
@ -569,6 +606,10 @@ Controller_function(mISDNinstance_t *inst, struct sk_buff *skb)
ret = ControllerNewPlci(contr, &plci, hh->dinfo);
if(!ret)
dev_kfree_skb(skb);
} else if (hh->prim == (MGR_SELCHANNEL | CONFIRM)) {
ret = ControllerSelChannel(contr, hh->dinfo, skb);
if(!ret)
dev_kfree_skb(skb);
} else if (hh->dinfo == MISDN_ID_DUMMY) {
contrDebug(contr, CAPI_DBG_CONTR_INFO, "%s: call Supplementary_l3l4 len %d",
__FUNCTION__, skb->len);
@ -732,33 +773,6 @@ ControllerConstr(Controller_t **contr_p, mISDNstack_t *st, mISDN_pid_t *pid, mIS
return retval;
}
PLInst_t *
ControllerSelChannel(Controller_t *contr, u_int channel)
{
mISDNstack_t *cst;
PLInst_t *plink;
channel_info_t ci;
int ret;
if (list_empty(&contr->linklist)) {
int_errtxt("no linklist for controller(%x)", contr->addr);
return(NULL);
}
ci.channel = channel;
ci.st.p = NULL;
ret = mISDN_ctrl(contr->inst.st, MGR_SELCHANNEL | REQUEST, &ci);
if (ret) {
int_errtxt("MGR_SELCHANNEL ret(%d)", ret);
return(NULL);
}
cst = ci.st.p;
list_for_each_entry(plink, &contr->linklist, list) {
if (cst == plink->st)
return(plink);
}
return(NULL);
}
int
ControllerNextId(Controller_t *contr)
{

View File

@ -56,6 +56,7 @@ typedef struct _mISDN_thread {
#define mISDN_TFLAGS_TEST 3
static mISDN_thread_t mISDN_thread;
DECLARE_COMPLETION(mISDN_thread_exit);
static moditem_t modlist[] = {
{"mISDN_l1", ISDN_PID_L1_TE_S0},
@ -150,6 +151,7 @@ mISDNd(void *data)
hkt->thread = NULL;
if (hkt->notify != NULL)
up(hkt->notify);
complete(&mISDN_thread_exit);
return(0);
}
@ -170,17 +172,11 @@ get_object(int id) {
static mISDNobject_t *
find_object(int protocol) {
mISDNobject_t *obj;
int err;
read_lock(&mISDN_objects_lock);
list_for_each_entry(obj, &mISDN_objectlist, list) {
err = obj->own_ctrl(NULL, MGR_HASPROTOCOL | REQUEST, &protocol);
if (!err)
if (0 == mISDN_HasProtocol(obj, protocol))
goto unlock;
if (err != -ENOPROTOOPT) {
if (0 == mISDN_HasProtocol(obj, protocol))
goto unlock;
}
}
obj = NULL;
unlock:
@ -263,7 +259,7 @@ get_next_instance(mISDNstack_t *st, mISDN_pid_t *pid)
__FUNCTION__);
return(NULL);
}
err = obj->own_ctrl(st, MGR_NEWLAYER | REQUEST, pid);
err = obj->getinst(st, pid);
if (err) {
printk(KERN_WARNING "%s: newlayer err(%d)\n",
__FUNCTION__, err);
@ -275,31 +271,23 @@ get_next_instance(mISDNstack_t *st, mISDN_pid_t *pid)
}
static int
sel_channel(mISDNstack_t *st, channel_info_t *ci)
sel_channel(mISDNstack_t *st, struct sk_buff *skb)
{
int err = -EINVAL;
mISDN_head_t *hh = mISDN_HEAD_P(skb);
mISDNstack_t *cst;
u_int nr = 0;
u_int *ch = (u_int *)skb->data;
int err = -EINVAL;
if (!ci)
return(err);
if (debug)
printk(KERN_DEBUG "%s: st(%p) st->mgr(%p)\n",
__FUNCTION__, st, st->mgr);
if (st->mgr) {
if (st->mgr->obj && st->mgr->obj->own_ctrl) {
err = st->mgr->obj->own_ctrl(st->mgr, MGR_SELCHANNEL | REQUEST, ci);
if (debug)
printk(KERN_DEBUG "%s: MGR_SELCHANNEL(%d)\n", __FUNCTION__, err);
} else
int_error();
err = st->mgr->function(st->mgr, skb);
if (debug)
printk(KERN_DEBUG "%s: MGR_SELCHANNEL(%d)\n", __FUNCTION__, err);
} else {
printk(KERN_WARNING "%s: no mgr st(%p)\n", __FUNCTION__, st);
}
if (err) {
mISDNstack_t *cst;
u_int nr = 0;
ci->st.p = NULL;
if (!(ci->channel & (~CHANNEL_NUMBER))) {
if (!(*ch & (~CHANNEL_NUMBER))) {
/* only number is set */
struct list_head *head;
if (list_empty(&st->childlist)) {
@ -315,9 +303,12 @@ sel_channel(mISDNstack_t *st, channel_info_t *ci)
head = &st->childlist;
list_for_each_entry(cst, head, list) {
nr++;
if (nr == (ci->channel & 3)) {
ci->st.p = cst;
return(0);
if (nr == (*ch & 0x1f)) {
*ch = cst->id;
hh->prim |= CONFIRM;
skb_queue_tail(&st->msgq, skb);
err = 0;
break;
}
}
}
@ -325,7 +316,7 @@ sel_channel(mISDNstack_t *st, channel_info_t *ci)
return(err);
}
#ifdef FIXME
#ifdef OBSOLETE
static int
disconnect_if(mISDNinstance_t *inst, u_int prim, mISDNif_t *hif) {
int err = 0;
@ -494,17 +485,22 @@ mISDN_delete_entity(int entity)
static int
new_entity(mISDNinstance_t *inst)
{
int entity;
int ret;
int entity;
int ret;
struct sk_buff *skb;
if (!inst)
return(-EINVAL);
if (!(skb = alloc_skb(4, GFP_ATOMIC)))
return(-ENOMEM);
ret = mISDN_alloc_entity(&entity);
if (ret) {
dev_kfree_skb(skb);
printk(KERN_WARNING "mISDN: no more entity available(max %d)\n", MISDN_MAX_ENTITY);
return(ret);
}
ret = inst->obj->own_ctrl(inst, MGR_NEWENTITY | CONFIRM, (void *)((u_long)entity));
mISDN_sethead(MGR_NEWENTITY | CONFIRM, entity, skb);
ret = mISDN_queue_message(inst, inst->id | FLG_MSG_TARGET, skb);
if (ret)
mISDN_delete_entity(entity);
return(ret);
@ -527,11 +523,7 @@ mISDN_ctrl(void *data, u_int prim, void *arg) {
case MGR_REGLAYER | INDICATION:
return(register_layer(st, arg));
case MGR_REGLAYER | REQUEST:
if (!register_layer(st, arg)) {
mISDNinstance_t *inst = arg;
return(inst->obj->own_ctrl(arg, MGR_REGLAYER | CONFIRM, NULL));
}
return(-EINVAL);
return(register_layer(st, arg));
case MGR_UNREGLAYER | REQUEST:
return(unregister_instance(data));
#ifdef FIXME
@ -585,8 +577,8 @@ mISDN_ctrl(void *data, u_int prim, void *arg) {
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));
#warning if (st->mgr && st->mgr->obj && st->mgr->obj->own_ctrl)
#warning return(st->mgr->obj->own_ctrl(st->mgr, prim, arg));
break;
case MGR_DEBUGDATA | REQUEST:
return(debugout(data, arg));
@ -608,7 +600,6 @@ int mISDN_register(mISDNobject_t *obj) {
obj->id = obj_id++;
list_add_tail(&obj->list, &mISDN_objectlist);
write_unlock_irqrestore(&mISDN_objects_lock, flags);
// register_prop
if (debug)
printk(KERN_DEBUG "mISDN_register %s id %x\n", obj->name,
obj->id);
@ -671,9 +662,11 @@ mISDNInit(void)
init_waitqueue_head(&mISDN_thread.waitq);
skb_queue_head_init(&mISDN_thread.workq);
mISDN_thread.notify = &sem;
kernel_thread(mISDNd, (void *)&mISDN_thread, 0);
// preempt_disable();
kernel_thread(mISDNd, (void *)&mISDN_thread, CLONE_KERNEL);
down(&sem);
mISDN_thread.notify = NULL;
// preempt_enable();
test_and_set_bit(mISDN_TFLAGS_TEST, &mISDN_thread.Flags);
wake_up_interruptible(&mISDN_thread.waitq);
return(err);
@ -688,8 +681,6 @@ sysfs_fail:
}
void mISDN_cleanup(void) {
DECLARE_MUTEX_LOCKED(sem);
free_mISDNdev();
if (!list_empty(&mISDN_objectlist)) {
printk(KERN_WARNING "mISDNcore mISDN_objects not empty\n");
@ -697,11 +688,14 @@ void mISDN_cleanup(void) {
check_stacklist();
if (mISDN_thread.thread) {
/* abort mISDNd kernel thread */
mISDN_thread.notify = &sem;
test_and_set_bit(mISDN_TFLAGS_RMMOD, &mISDN_thread.Flags);
// preempt_disable();
printk(KERN_WARNING "xxx1\n");
wake_up_interruptible(&mISDN_thread.waitq);
down(&sem);
mISDN_thread.notify = NULL;
printk(KERN_WARNING "xxx2\n");
wait_for_completion(&mISDN_thread_exit);
printk(KERN_WARNING "xxx4\n");
// preempt_enable();
}
#ifdef MISDN_MEMDEBUG
__mid_cleanup();
@ -712,7 +706,6 @@ void mISDN_cleanup(void) {
module_init(mISDNInit);
module_exit(mISDN_cleanup);
EXPORT_SYMBOL(mISDN_ctrl);
EXPORT_SYMBOL(mISDN_register);
EXPORT_SYMBOL(mISDN_unregister);

View File

@ -803,7 +803,27 @@ new_dsp(mISDNstack_t *st, mISDN_pid_t *pid)
return(err);
}
static int
dsp_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
mISDNinstance_t *inst = NULL;
dsp_t *dspl;
u_long flags;
spin_lock_irqsave(&dsp_obj.lock, flags);
list_for_each_entry(dspl, &dsp_obj.ilist, list) {
if (dspl->inst.st == st) {
inst =&dspl->inst;
break;
}
}
spin_unlock_irqrestore(&dsp_obj.lock, flags);
if (inst)
return(-EBUSY);
return(new_dsp(st, pid));
}
#ifdef OBSOLETE
/*
* manager for DSP instances
*/
@ -864,7 +884,7 @@ dsp_manager(void *data, u_int prim, void *arg) {
}
return(ret);
}
#endif
/*
* initialize DSP object
@ -914,7 +934,7 @@ static int dsp_init(void)
spin_lock_init(&dsp_obj.lock);
dsp_obj.name = DSPName;
dsp_obj.BPROTO.protocol[3] = ISDN_PID_L3_B_DSP;
dsp_obj.own_ctrl = dsp_manager;
dsp_obj.getinst = dsp_instance;
INIT_LIST_HEAD(&dsp_obj.ilist);
/* initialize audio tables */

View File

@ -566,6 +566,27 @@ MODULE_LICENSE("GPL");
#endif
#endif
static int
dtmf_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
mISDNinstance_t *inst = NULL;
dtmf_t *dtmf;
u_long flags;
spin_lock_irqsave(&dtmf_obj.lock, flags);
list_for_each_entry(dtmf, &dtmf_obj.ilist, list) {
if (dtmf->inst.st == st) {
inst =&dtmf->inst;
break;
}
}
spin_unlock_irqrestore(&dtmf_obj.lock, flags);
if (inst)
return(-EBUSY);
return(new_dtmf(st, pid));
}
#ifdef OBSOLETE
static int
dtmf_manager(void *data, u_int prim, void *arg) {
mISDNinstance_t *inst = data;
@ -621,6 +642,7 @@ dtmf_manager(void *data, u_int prim, void *arg) {
}
return(0);
}
#endif
static int dtmf_init(void)
{
@ -632,7 +654,7 @@ static int dtmf_init(void)
#endif
dtmf_obj.name = MName;
dtmf_obj.BPROTO.protocol[2] = ISDN_PID_L2_B_TRANSDTMF;
dtmf_obj.own_ctrl = dtmf_manager;
dtmf_obj.getinst = dtmf_instance;
spin_lock_init(&dtmf_obj.lock);
INIT_LIST_HEAD(&dtmf_obj.ilist);
if ((err = mISDN_register(&dtmf_obj))) {

View File

@ -349,6 +349,10 @@ mISDN_init_instance(mISDNinstance_t *inst, mISDNobject_t *obj, void *data, if_fu
int_error();
return;
}
if (!obj->getinst) {
int_error();
return;
}
INIT_LIST_HEAD(&inst->list);
inst->obj = obj;
inst->privat = data;

View File

@ -285,13 +285,4 @@ extern void mISDN_LogL3Msg(struct sk_buff *);
#define PRIM_NOT_HANDLED(p) case p: break
#define MGR_HASPROTOCOL_HANDLER(p,a,o) \
if ((MGR_HASPROTOCOL | REQUEST) == p) {\
if (a) {\
int prot = *((int *)a);\
return(mISDN_HasProtocol(o, prot));\
} else \
return(-EINVAL);\
}
#endif /* _mISDN_HELPER_H */

View File

@ -3087,6 +3087,34 @@ release_port(hfc_multi_t *hc, int port)
}
}
static int
HFC_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
hfc_multi_t *hc;
mISDNinstance_t *inst = NULL;
u_long flags;
spin_lock_irqsave(&HFCM_obj.lock, flags);
list_for_each_entry(hc, &HFCM_obj.ilist, list) {
int i = 0;
while(i < 32) {
if ((hc->chan[i].ch) &&
(hc->chan[i].ch->inst.st == st)) {
inst = &hc->chan[i].ch->inst;
break;
}
i++;
}
if (inst)
break;
}
spin_unlock_irqrestore(&HFCM_obj.lock, flags);
if (!inst)
return(-EINVAL);
return(mISDN_ctrl(st, MGR_REGLAYER | REQUEST, inst));
}
#ifdef OBSOLETE
static int
HFC_manager(void *data, u_int prim, void *arg)
{
@ -3222,6 +3250,7 @@ bugtest
}
return(0);
}
#endif
static void find_type_entry(int hfc_type, int *card, int *port)
{
@ -3680,8 +3709,8 @@ free_delstack:
spin_unlock_irqrestore(&hc->lock, flags);
return(0);
/* if an error ocurred */
free_channels:
/* if an error ocurred */
free_channels:
i = 0;
while(i < 32) {
if (hc->chan[i].ch) {
@ -3867,7 +3896,7 @@ HFCmulti_init(void)
spin_lock_init(&HFCM_obj.lock);
INIT_LIST_HEAD(&HFCM_obj.ilist);
HFCM_obj.name = HFCName;
HFCM_obj.own_ctrl = HFC_manager;
HFCM_obj.getinst = HFC_instance;
HFCM_obj.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0 | ISDN_PID_L0_NT_S0
| ISDN_PID_L0_TE_E1 | ISDN_PID_L0_NT_E1;
HFCM_obj.DPROTO.protocol[1] = ISDN_PID_L1_NT_S0

View File

@ -1958,6 +1958,35 @@ release_card(hfc_pci_t *hc) {
kfree(hc);
}
static int
HFC_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
hfc_pci_t *card;
mISDNinstance_t *inst = NULL;
u_long flags;
spin_lock_irqsave(&HFC_obj.lock, flags);
list_for_each_entry(card, &HFC_obj.ilist, list) {
if (card->dch.inst.st == st) {
inst = &card->dch.inst;
break;
}
if (card->bch[0].inst.st == st) {
inst = &card->bch[0].inst;
break;
}
if (card->bch[1].inst.st == st) {
inst = &card->bch[1].inst;
break;
}
}
spin_unlock_irqrestore(&HFC_obj.lock, flags);
if (!inst)
return(-EINVAL);
return(mISDN_ctrl(st, MGR_REGLAYER | REQUEST, inst));
}
#ifdef OBSOLETE
static int
HFC_manager(void *data, u_int prim, void *arg) {
hfc_pci_t *card;
@ -2070,6 +2099,7 @@ HFC_manager(void *data, u_int prim, void *arg) {
}
return(0);
}
#endif
static int __init HFC_init(void)
{
@ -2085,7 +2115,7 @@ static int __init HFC_init(void)
spin_lock_init(&HFC_obj.lock);
INIT_LIST_HEAD(&HFC_obj.ilist);
HFC_obj.name = HFCName;
HFC_obj.own_ctrl = HFC_manager;
HFC_obj.getinst = HFC_instance;
HFC_obj.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0 |
ISDN_PID_L0_NT_S0;
HFC_obj.DPROTO.protocol[1] = ISDN_PID_L1_NT_S0;

View File

@ -536,6 +536,34 @@ hfcsmini_l2l1(mISDNinstance_t *inst, struct sk_buff *skb)
}
static int
hfcsmini_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
hfcsmini_hw *hc;
mISDNinstance_t *inst = NULL;
u_long flags;
spin_lock_irqsave(&hw_mISDNObj.lock, flags);
list_for_each_entry(hc, &hw_mISDNObj.ilist, list) {
int i = 0;
while(i < 32) {
if (hc->chan[i].inst.st == st) {
inst = &hc->chan[i].inst;
break;
}
i++;
}
if (i < 32)
break;
}
spin_unlock_irqrestore(&hw_mISDNObj.lock, flags);
if (!inst)
return(-EINVAL);
return(mISDN_ctrl(st, MGR_REGLAYER | REQUEST, inst));
}
#ifdef OBSOLETE
static int
hfcsmini_manager(void *data, u_int prim, void *arg)
{
@ -641,7 +669,7 @@ hfcsmini_manager(void *data, u_int prim, void *arg)
}
return (0);
}
#endif
/***********************************/
/* check if new buffer for channel */
@ -1297,8 +1325,8 @@ init_mISDN_channels(hfcsmini_hw * hw)
err = mISDN_ctrl(hw->chan[ch].inst.st, MGR_NEWSTACK | REQUEST, &hw->chan[b].inst);
if (err) {
printk(KERN_ERR
"%s %s: MGR_ADDSTACK bchan error %d\n",
hw->card_name, __FUNCTION__, err);
"%s %s: MGR_ADDSTACK bchan error %d\n",
hw->card_name, __FUNCTION__, err);
goto free_stack;
}
}
@ -1306,9 +1334,8 @@ init_mISDN_channels(hfcsmini_hw * hw)
err = mISDN_ctrl(hw->chan[ch].inst.st, MGR_SETSTACK | REQUEST, &pid);
if (err) {
printk(KERN_ERR
"%s %s: MGR_SETSTACK REQUEST dch err(%d)\n",
hw->card_name, __FUNCTION__, err);
printk(KERN_ERR "%s %s: MGR_SETSTACK REQUEST dch err(%d)\n",
hw->card_name, __FUNCTION__, err);
mISDN_ctrl(hw->chan[ch].inst.st, MGR_DELSTACK | REQUEST, NULL);
goto free_stack;
}
@ -1809,7 +1836,7 @@ hfcsmini_init(void)
INIT_LIST_HEAD(&hw_mISDNObj.ilist);
spin_lock_init(&hw_mISDNObj.lock);
hw_mISDNObj.name = DRIVER_NAME;
hw_mISDNObj.own_ctrl = hfcsmini_manager;
hw_mISDNObj.getinst = hfcsmini_instance;
hw_mISDNObj.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0 |
ISDN_PID_L0_NT_S0;

View File

@ -802,6 +802,33 @@ hfcsusb_l2l1(mISDNinstance_t *inst, struct sk_buff *skb)
}
static int
hfcsusb_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
hfcsusb_t *card;
mISDNinstance_t *inst = NULL;
u_long flags;
spin_lock_irqsave(&hw_mISDNObj.lock, flags);
list_for_each_entry(card, &hw_mISDNObj.ilist, list) {
int i = 0;
while(i < 4) {
if (card->chan[i].inst.st == st) {
inst = &card->chan[i].inst;
break;
}
i++;
}
if (i < 4)
break;
}
spin_unlock_irqrestore(&hw_mISDNObj.lock, flags);
if (!inst)
return(-EINVAL);
return(mISDN_ctrl(st, MGR_REGLAYER | REQUEST, inst));
}
#ifdef OBSOLETE
static int
hfcsusb_manager(void *data, u_int prim, void *arg)
{
@ -907,6 +934,7 @@ hfcsusb_manager(void *data, u_int prim, void *arg)
}
return (0);
}
#endif
/***********************************************/
@ -1969,7 +1997,7 @@ hfcsusb_init(void)
spin_lock_init(&hw_mISDNObj.lock);
INIT_LIST_HEAD(&hw_mISDNObj.ilist);
hw_mISDNObj.name = DRIVER_NAME;
hw_mISDNObj.own_ctrl = hfcsusb_manager;
hw_mISDNObj.getinst = hfcsusb_instance;
hw_mISDNObj.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0 |
ISDN_PID_L0_NT_S0;

View File

@ -392,7 +392,7 @@ isar_load_firmware(channel_t *bch, u_char *buf, int size)
spin_lock_irqsave(bch->inst.hwlock, flags);
isar_setup(bch);
spin_unlock_irqrestore(bch->inst.hwlock, flags);
bch->inst.obj->own_ctrl(&bch->inst, MGR_LOADFIRM | CONFIRM, NULL);
#warning bch->inst.obj->own_ctrl(&bch->inst, MGR_LOADFIRM | CONFIRM, NULL);
ret = 0;
reterrflg:
spin_lock_irqsave(bch->inst.hwlock, flags);

View File

@ -2925,6 +2925,26 @@ MODULE_LICENSE("GPL");
module_param(debug, uint, S_IRUGO | S_IWUSR);
#endif
static int
udss1_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
layer3_t *l3l;
u_long flags;
spin_lock_irqsave(&u_dss1.lock, flags);
list_for_each_entry(l3l, &u_dss1.ilist, list) {
if (l3l->inst.st == st) {
spin_unlock_irqrestore(&u_dss1.lock, flags);
return(-EBUSY);
}
}
if (&l3l->list == &u_dss1.ilist)
l3l = NULL;
spin_unlock_irqrestore(&u_dss1.lock, flags);
return(new_udss1(st, pid));
}
#ifdef OBSOLETE
static int
udss1_manager(void *data, u_int prim, void *arg) {
mISDNinstance_t *inst = data;
@ -2982,6 +3002,7 @@ udss1_manager(void *data, u_int prim, void *arg) {
}
return(0);
}
#endif
int UDSS1Init(void)
{
@ -3000,7 +3021,7 @@ int UDSS1Init(void)
ISDN_PID_L3_DF_PTP |
ISDN_PID_L3_DF_EXTCID |
ISDN_PID_L3_DF_CRLEN2;
u_dss1.own_ctrl = udss1_manager;
u_dss1.getinst = udss1_instance;
mISDNl3New();
if ((err = mISDN_register(&u_dss1))) {
printk(KERN_ERR "Can't register %s error(%d)\n", MName, err);

View File

@ -744,6 +744,27 @@ MODULE_LICENSE("GPL");
#define Isdnl1Init init_module
#endif
static int
l1_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
mISDNinstance_t *inst = NULL;
layer1_t *l1;
u_long flags;
spin_lock_irqsave(&isdnl1.lock, flags);
list_for_each_entry(l1, &isdnl1.ilist, list) {
if (l1->inst.st == st) {
inst =&l1->inst;
break;
}
}
spin_unlock_irqrestore(&isdnl1.lock, flags);
if (inst)
return(-EBUSY);
return(new_l1(st, pid));
}
#ifdef OBSOLETE
static int
l1_manager(void *data, u_int prim, void *arg) {
mISDNinstance_t *inst = data;
@ -803,6 +824,7 @@ l1_manager(void *data, u_int prim, void *arg) {
}
return(err);
}
#endif
int Isdnl1Init(void)
{
@ -814,7 +836,7 @@ int Isdnl1Init(void)
#endif
isdnl1.name = MName;
isdnl1.DPROTO.protocol[1] = ISDN_PID_L1_TE_S0;
isdnl1.own_ctrl = l1_manager;
isdnl1.getinst = l1_instance;
spin_lock_init(&isdnl1.lock);
INIT_LIST_HEAD(&isdnl1.ilist);
#ifdef mISDN_UINTERFACE

View File

@ -2411,6 +2411,27 @@ MODULE_LICENSE("GPL");
module_param(debug, uint, S_IRUGO | S_IWUSR);
#endif
static int
l2_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
mISDNinstance_t *inst = NULL;
layer2_t *l2;
u_long flags;
spin_lock_irqsave(&isdnl2.lock, flags);
list_for_each_entry(l2, &isdnl2.ilist, list) {
if (l2->inst.st == st) {
inst =&l2->inst;
break;
}
}
spin_unlock_irqrestore(&isdnl2.lock, flags);
if (inst)
return(-EBUSY);
return(new_l2(st, pid));
}
#ifdef OBSOLETE
static int
l2_manager(void *data, u_int prim, void *arg) {
mISDNinstance_t *inst = data;
@ -2481,6 +2502,7 @@ l2_manager(void *data, u_int prim, void *arg) {
}
return(0);
}
#endif
int Isdnl2_Init(void)
{
@ -2495,7 +2517,7 @@ int Isdnl2_Init(void)
ISDN_PID_L2_LAPD_NET |
ISDN_PID_L2_DF_PTP;
isdnl2.BPROTO.protocol[2] = ISDN_PID_L2_B_X75SLP;
isdnl2.own_ctrl = l2_manager;
isdnl2.getinst = l2_instance;
spin_lock_init(&isdnl2.lock);
INIT_LIST_HEAD(&isdnl2.ilist);
l2fsm.state_count = L2_STATE_COUNT;

View File

@ -249,6 +249,7 @@ struct _AppPlci {
Application_t *appl;
Controller_t *contr;
PLInst_t *link;
int linkid;
struct sk_buff_head delayedq;
struct list_head Nccis;
struct FsmInst plci_m;
@ -314,7 +315,6 @@ Application_t *getApplication4Id(Controller_t *, __u16);
Plci_t *getPlci4Addr(Controller_t *, __u32);
int ControllerL4L3(Controller_t *, u_int, int, 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);
int ControllerNextId(Controller_t *);
@ -406,19 +406,19 @@ void SendSSNotificationEvent(AppPlci_t *, u16);
// INFOMASK defines (LISTEN commands)
// ---------------------------------------------------------------------------
#define CAPI_INFOMASK_CAUSE 0x0001
#define CAPI_INFOMASK_DATETIME 0x0002
#define CAPI_INFOMASK_DISPLAY 0x0004
#define CAPI_INFOMASK_USERUSER 0x0008
#define CAPI_INFOMASK_PROGRESS 0x0010
#define CAPI_INFOMASK_FACILITY 0x0020
#define CAPI_INFOMASK_CHARGE 0x0040
#define CAPI_INFOMASK_CALLEDPN 0x0080
#define CAPI_INFOMASK_CHANNELID 0x0100
#define CAPI_INFOMASK_EARLYB3 0x0200
#define CAPI_INFOMASK_REDIRECT 0x0400
#define CAPI_INFOMASK_CAUSE (0x0001)
#define CAPI_INFOMASK_DATETIME (0x0002)
#define CAPI_INFOMASK_DISPLAY (0x0004)
#define CAPI_INFOMASK_USERUSER (0x0008)
#define CAPI_INFOMASK_PROGRESS (0x0010)
#define CAPI_INFOMASK_FACILITY (0x0020)
#define CAPI_INFOMASK_CHARGE (0x0040)
#define CAPI_INFOMASK_CALLEDPN (0x0080)
#define CAPI_INFOMASK_CHANNELID (0x0100)
#define CAPI_INFOMASK_EARLYB3 (0x0200)
#define CAPI_INFOMASK_REDIRECT (0x0400)
/* bit 11 reserved */
#define CAPI_INFOMASK_COMPLETE 0x1000
#define CAPI_INFOMASK_COMPLETE 0x1000
/* bit 13-31 reserved */
// ---------------------------------------------------------------------------

View File

@ -380,14 +380,14 @@ ncci_manufacturer_req(struct FsmInst *fi, int event, void *arg)
_cmsg *cmsg = arg;
int err, op;
struct _manu_conf_para {
u8 len;
u16 Info;
u16 vol;
u8 len __attribute__((packed));
u16 Info __attribute__((packed));
u16 vol __attribute__((packed));
} mcp = {2, CAPI_NOERROR,0};
struct _manu_req_para {
u8 len;
u16 vol;
} __attribute__((packed)) *mrp;
u8 len __attribute__((packed));
u16 vol __attribute__((packed));
} *mrp;
if (!ncci->appl)
return;

View File

@ -518,6 +518,35 @@ release_card(sedl_fax *card) {
sedl_cnt--;
}
static int
speedfax_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
sedl_fax *card;
mISDNinstance_t *inst = NULL;
u_long flags;
spin_lock_irqsave(&speedfax.lock, flags);
list_for_each_entry(card, &speedfax.ilist, list) {
if (card->dch.inst.st == st) {
inst = &card->dch.inst;
break;
}
if (card->bch[0].inst.st == st) {
inst = &card->bch[0].inst;
break;
}
if (card->bch[1].inst.st == st) {
inst = &card->bch[1].inst;
break;
}
}
spin_unlock_irqrestore(&speedfax.lock, flags);
if (!inst)
return(-EINVAL);
return(mISDN_ctrl(st, MGR_REGLAYER | REQUEST, inst));
}
#ifdef OBSOLETE
static int
speedfax_manager(void *data, u_int prim, void *arg) {
sedl_fax *card;
@ -646,6 +675,7 @@ speedfax_manager(void *data, u_int prim, void *arg) {
}
return(0);
}
#endif
static int __devinit setup_instance(sedl_fax *card)
{
@ -892,7 +922,7 @@ static int __init Speedfax_init(void)
spin_lock_init(&speedfax.lock);
INIT_LIST_HEAD(&speedfax.ilist);
speedfax.name = SpeedfaxName;
speedfax.own_ctrl = speedfax_manager;
speedfax.getinst = speedfax_instance;
speedfax.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0;
speedfax.BPROTO.protocol[1] = ISDN_PID_L1_B_64TRANS |
ISDN_PID_L1_B_64HDLC |

View File

@ -358,6 +358,7 @@ mISDN_queue_message(mISDNinstance_t *inst, u_int aflag, struct sk_buff *skb)
mISDNstack_t *st = inst->st;
u_int id;
preempt_disable();
if (core_debug & DEBUG_QUEUE_FUNC)
printk(KERN_DEBUG "%s(%08x, %x, prim(%x))\n", __FUNCTION__,
inst->id, aflag, hh->prim);
@ -373,24 +374,31 @@ mISDN_queue_message(mISDNinstance_t *inst, u_int aflag, struct sk_buff *skb)
id = (inst->id & INST_ID_MASK) | FLG_MSG_TARGET | FLG_MSG_CLONED | FLG_MSG_DOWN;
}
}
if (!st)
if (unlikely(!st)) {
preempt_enable();
return(-EINVAL);
if (st->id == 0 || test_bit(mISDN_STACK_ABORT, &st->status))
}
if (unlikely(st->id == 0 || test_bit(mISDN_STACK_ABORT, &st->status))) {
preempt_enable();
return(-EBUSY);
}
if (inst->id == 0) { /* instance is not initialised */
if (!(aflag & FLG_MSG_TARGET)) {
id &= INST_ID_MASK;
id |= (st->id & INST_ID_MASK) | aflag | FLG_INSTANCE;
}
}
if (test_bit(mISDN_STACK_KILLED, &st->status))
if (unlikely(test_bit(mISDN_STACK_KILLED, &st->status))) {
preempt_enable();
return(-EBUSY);
}
if ((st->id & STACK_ID_MASK) != (id & STACK_ID_MASK)) {
int_errtxt("stack id not match st(%08x) id(%08x) inst(%08x) aflag(%08x) prim(%x)",
st->id, id, inst->id, aflag, hh->prim);
}
hh->addr = id;
_queue_message(st, skb);
preempt_enable();
return(0);
}
@ -447,7 +455,7 @@ release_layers(mISDNstack_t *st, u_int prim)
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);
#warning st->i_array[i]->obj->own_ctrl(st->i_array[i], prim, NULL);
}
}
}
@ -478,6 +486,8 @@ mISDNStackd(void *data)
#ifdef CONFIG_SMP
unlock_kernel();
#endif
allow_signal(SIGTERM);
preempt_disable();
printk(KERN_DEBUG "mISDNStackd started for id(%08x)\n", st->id);
for (;;) {
struct sk_buff *skb, *c_skb;
@ -517,6 +527,16 @@ mISDNStackd(void *data)
st->notify = hhe->data[0];
}
dev_kfree_skb(skb);
printk(KERN_DEBUG "%s: st(%08x) clearing setup\n", __FUNCTION__, st->id);
continue;
}
if (hh->prim == (MGR_SELCHANNEL | REQUEST)) {
err = mISDN_ctrl(st, MGR_SELCHANNEL | REQUEST, skb);
if (err) {
skb_trim(skb, 0);
hh->prim |= CONFIRM;
skb_queue_tail(&st->msgq, skb);
}
continue;
}
if ((hh->addr & MSG_DIR_MASK) == MSG_BROADCAST) {
@ -600,8 +620,16 @@ mISDNStackd(void *data)
#ifdef MISDN_MSG_STATS
st->sleep_cnt++;
#endif
preempt_enable();
test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status);
wait_event_interruptible(st->workq, (st->status & mISDN_STACK_ACTION_MASK));
err = wait_event_interruptible(st->workq, (st->status & mISDN_STACK_ACTION_MASK));
preempt_disable();
if (err) {
printk(KERN_INFO "%s: st(%08x) got signal err=%d status=%08lx\n",
__FUNCTION__, st->id, err, st->status);
break;
}
if (core_debug & DEBUG_MSG_THREAD_INFO)
printk(KERN_DEBUG "%s: %08x wake status %08lx\n", __FUNCTION__, st->id, st->status);
test_and_set_bit(mISDN_STACK_ACTIVE, &st->status);
@ -632,6 +660,8 @@ mISDNStackd(void *data)
up(st->notify);
st->notify = NULL;
}
printk(KERN_DEBUG "mISDNStackd id(%08x) xxx7\n", st->id);
preempt_enable();
return(0);
}
@ -642,7 +672,12 @@ mISDN_start_stack_thread(mISDNstack_t *st)
if (st->thread == NULL && test_bit(mISDN_STACK_KILLED, &st->status)) {
test_and_clear_bit(mISDN_STACK_KILLED, &st->status);
kernel_thread(mISDNStackd, (void *)st, 0);
st->thread_id = kernel_thread(mISDNStackd, (void *)st, 0);
if (!st->thread_id) {
err = -EBUSY;
test_and_set_bit(mISDN_STACK_KILLED, &st->status);
printk(KERN_ERR "cannot start thread for stack id %08x\n", st->id);
}
} else
err = -EBUSY;
return(err);
@ -651,7 +686,7 @@ mISDN_start_stack_thread(mISDNstack_t *st)
mISDNstack_t *
new_stack(mISDNstack_t *master, mISDNinstance_t *inst)
{
mISDNstack_t *newst;
mISDNstack_t *newst, *clone = NULL;
int err;
u_long flags;
@ -670,13 +705,12 @@ new_stack(mISDNstack_t *master, mISDNinstance_t *inst)
skb_queue_head_init(&newst->msgq);
if (!master) {
if (inst && inst->st) {
master = inst->st;
while(master->clone)
master = master->clone;
clone = inst->st;
while(clone->clone)
clone = clone->clone;
newst->id = get_free_stackid(inst->st, FLG_CLONE_STACK);
newst->master = master;
master->clone = newst;
master = NULL;
newst->master = clone;
clone->clone = newst;
} else {
newst->id = get_free_stackid(NULL, 0);
}
@ -697,13 +731,30 @@ new_stack(mISDNstack_t *master, mISDNinstance_t *inst)
}
err = mISDN_register_sysfs_stack(newst);
if (err) {
// FIXME error handling
printk(KERN_ERR "Stack id %x not registered in sysfs\n", newst->id);
printk(KERN_ERR "Stack id %08x not registered in sysfs\n", newst->id);
goto err_sysfs;
}
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "Stack id %x added\n", newst->id);
kernel_thread(mISDNStackd, (void *)newst, 0);
return(newst);
printk(KERN_DEBUG "Stack id %08x added\n", newst->id);
newst->thread_id = kernel_thread(mISDNStackd, (void *)newst, CLONE_KERNEL);
if (newst->thread_id) {
printk(KERN_INFO "mISDN stack %08x thread %d started\n", newst->id, newst->thread_id);
return(newst);
}
printk(KERN_ERR "cannot start thread for stack id %08x\n", newst->id);
mISDN_unregister_sysfs_st(newst);
err_sysfs:
if (inst)
inst->st = NULL;
if (clone)
clone->clone = NULL;
write_lock_irqsave(&stacklist_lock, flags);
list_del(&newst->list);
write_unlock_irqrestore(&stacklist_lock, flags);
kfree(newst);
return(NULL);
}
int
@ -738,7 +789,7 @@ do_for_all_layers(void *data, u_int prim, void *arg)
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);
#warning st->i_array[i]->obj->own_ctrl(st->i_array[i], prim, arg);
}
}
return(0);
@ -785,11 +836,13 @@ static int
delete_stack(mISDNstack_t *st)
{
DECLARE_MUTEX_LOCKED(sem);
u_long flags;
u_long flags = 0;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: st(%p:%08x)\n", __FUNCTION__, st, st->id);
printk(KERN_DEBUG "mISDNStackd id(%08x) xxx1\n", st->id);
mISDN_unregister_sysfs_st(st);
printk(KERN_DEBUG "mISDNStackd id(%08x) xxx2\n", st->id);
if (st->parent)
st->parent = NULL;
if (!list_empty(&st->prereg)) {
@ -828,7 +881,7 @@ release_stack(mISDNstack_t *st) {
mISDNstack_t *cst, *nst;
if (core_debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: st(%p)\n", __FUNCTION__, st);
printk(KERN_DEBUG "%s: st(%08x) %p\n", __FUNCTION__, st->id, st);
list_for_each_entry_safe(cst, nst, &st->childlist, list) {
if ((err = delete_stack(cst))) {
@ -866,7 +919,7 @@ cleanup_object(mISDNobject_t *obj)
inst = st->i_array[i];
if (inst && inst->obj == obj) {
read_unlock(&stacklist_lock);
inst->obj->own_ctrl(st, MGR_RELEASE | INDICATION, inst);
#warning inst->obj->own_ctrl(st, MGR_RELEASE | INDICATION, inst);
read_lock(&stacklist_lock);
}
}
@ -915,6 +968,7 @@ release_stacks(mISDNobject_t *obj)
rel++;
}
if (rel) {
printk(KERN_WARNING "release_stacks obj %s do it\n", obj->name);
read_unlock(&stacklist_lock);
release_stack(st);
read_lock(&stacklist_lock);
@ -1198,11 +1252,11 @@ set_stack(mISDNstack_t *st, mISDN_pid_t *pid)
int_error();
continue;
}
if (!inst->obj->own_ctrl) {
int_error();
continue;
}
inst->obj->own_ctrl(inst, MGR_SETSTACK | INDICATION, NULL);
#warning if (!inst->obj->own_ctrl) {
#warning int_error();
#warning continue;
#warning }
#warning inst->obj->own_ctrl(inst, MGR_SETSTACK | INDICATION, NULL);
}
return(0);
}

View File

@ -345,8 +345,8 @@ sel_channel(u_int addr, u_int channel)
return(NULL);
ci.channel = channel;
ci.st.p = NULL;
if (mISDN_ctrl(st, MGR_SELCHANNEL | REQUEST, &ci))
return(NULL);
#warning if (mISDN_ctrl(st, MGR_SELCHANNEL | REQUEST, &ci))
#warning return(NULL);
return(ci.st.p);
}
@ -393,7 +393,7 @@ create_layer(mISDNdevice_t *dev, struct sk_buff *skb)
__FUNCTION__, linfo->object_id);
return(-ENODEV);
}
ret = obj->own_ctrl(st, MGR_NEWLAYER | REQUEST, &linfo->pid);
ret = obj->getinst(st, &linfo->pid);
if (ret) {
printk(KERN_WARNING "%s: error nl req %d\n",
__FUNCTION__, ret);
@ -441,7 +441,7 @@ create_layer(mISDNdevice_t *dev, struct sk_buff *skb)
memset(pid->pbuf, 0, inst->pid.maxplen);
}
copy_pid(pid, &inst->pid, pid->pbuf);
ret = inst->obj->own_ctrl(st, MGR_NEWLAYER | REQUEST, pid);
ret = inst->obj->getinst(st, pid);
kfree(pid->pbuf);
kfree(pid);
if (ret) {
@ -508,8 +508,8 @@ create_layer(mISDNdevice_t *dev, struct sk_buff *skb)
st->mgr = &nl->inst;
test_and_set_bit(FLG_MGR_OWNSTACK, &nl->Flags);
}
if (st)
mISDN_ctrl(st, MGR_ADDLAYER | REQUEST, &nl->inst);
#warning if (st)
#warning nl->inst.obj->ctrl(st, MGR_ADDLAYER | REQUEST, &nl->inst);
} else {
nl->slave = inst;
nl->inst.extentions |= EXT_INST_UNUSED;
@ -563,10 +563,9 @@ del_layer(devicelayer_t *dl)
__FUNCTION__, dl->id, inst->id, inst->name, dl->slave);
}
if (dl->slave) {
if (dl->slave->obj)
dl->slave->obj->own_ctrl(dl->slave,
MGR_UNREGLAYER | REQUEST, NULL);
else
#warning if (dl->slave->obj)
#warning dl->slave->obj->own_ctrl(dl->slave, MGR_UNREGLAYER | REQUEST, NULL);
#warning else
dl->slave = NULL;
}
if (dl->lm_st && inst->st) {
@ -982,9 +981,8 @@ dev_init_timer(mISDNdevice_t *dev, u_int id)
} else if (device_debug & DEBUG_DEV_TIMER)
printk(KERN_DEBUG "%s: old(%x)\n", __FUNCTION__, ht->id);
if (timer_pending(&ht->tl)) {
if (device_debug & DEBUG_DEV_TIMER)
printk(KERN_WARNING "%s: timer(%x) pending\n",
__FUNCTION__, ht->id);
printk(KERN_WARNING "%s: timer(%x) pending\n", __FUNCTION__,
ht->id);
del_timer(&ht->tl);
}
init_timer(&ht->tl);
@ -1038,11 +1036,9 @@ dev_del_timer(mISDNdevice_t *dev, u_int id)
printk(KERN_DEBUG "%s: timer(%x)\n",
__FUNCTION__, ht->id);
del_timer(&ht->tl);
if (!test_and_clear_bit(FLG_MGR_TIMER_RUNING, &ht->Flags)) {
if (device_debug & DEBUG_DEV_TIMER)
printk(KERN_WARNING "%s: timer(%x) not running\n",
__FUNCTION__, ht->id);
}
if (!test_and_clear_bit(FLG_MGR_TIMER_RUNING, &ht->Flags))
printk(KERN_WARNING "%s: timer(%x) not running\n",
__FUNCTION__, ht->id);
return(0);
}
@ -1083,7 +1079,7 @@ get_status(struct sk_buff *skb)
printk(KERN_WARNING "%s: no instance\n", __FUNCTION__);
err = -ENODEV;
} else {
err = inst->obj->own_ctrl(inst, MGR_STATUS | REQUEST, si);
#warning err = inst->obj->own_ctrl(inst, MGR_STATUS | REQUEST, si);
}
if (err)
hp->len = err;
@ -1890,6 +1886,31 @@ static void setstack_conf(devicelayer_t *dl)
kfree_skb(skb);
}
static int
udev_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
mISDNinstance_t *inst = NULL;
mISDNdevice_t *dev;
devicelayer_t *dl;
read_lock(&mISDN_device_lock);
list_for_each_entry(dev, &mISDN_devicelist, list) {
list_for_each_entry(dl, &dev->layerlist, list) {
if (dl->inst.st == st) {
inst = &dl->inst;
break;
}
}
if (inst)
break;
}
read_unlock(&mISDN_device_lock);
if (!inst)
return(-EINVAL);
return(mISDN_ctrl(st, MGR_REGLAYER | REQUEST, inst));
}
#ifdef OBSOLETE
static int
udev_manager(void *data, u_int prim, void *arg) {
mISDNinstance_t *inst = data;
@ -1954,6 +1975,7 @@ out:
read_unlock(&mISDN_device_lock);
return(err);
}
#endif
int init_mISDNdev (int debug) {
int err,i;
@ -1966,7 +1988,7 @@ int init_mISDNdev (int debug) {
}
spin_lock_init(&udev_obj.lock);
INIT_LIST_HEAD(&udev_obj.ilist);
udev_obj.own_ctrl = udev_manager;
udev_obj.getinst = udev_instance;
device_debug = debug;
if (register_chrdev(mISDN_MAJOR, "mISDN", &mISDN_fops)) {

View File

@ -1309,6 +1309,35 @@ release_card(w6692pci *card)
kfree(card);
}
static int
w6692_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
w6692pci *card;
mISDNinstance_t *inst = NULL;
u_long flags;
spin_lock_irqsave(&w6692.lock, flags);
list_for_each_entry(card, &w6692.ilist, list) {
if (card->dch.inst.st == st) {
inst = &card->dch.inst;
break;
}
if (card->bch[0].inst.st == st) {
inst = &card->bch[0].inst;
break;
}
if (card->bch[1].inst.st == st) {
inst = &card->bch[1].inst;
break;
}
}
spin_unlock_irqrestore(&w6692.lock, flags);
if (!inst)
return(-EINVAL);
return(mISDN_ctrl(st, MGR_REGLAYER | REQUEST, inst));
}
#ifdef OBSOLETE
static int
w6692_manager(void *data, u_int prim, void *arg) {
w6692pci *card;
@ -1415,6 +1444,7 @@ w6692_manager(void *data, u_int prim, void *arg) {
}
return(0);
}
#endif
static int setup_instance(w6692pci *card)
{
@ -1563,7 +1593,7 @@ static int __init w6692_init(void)
spin_lock_init(&w6692.lock);
INIT_LIST_HEAD(&w6692.ilist);
w6692.name = W6692Name;
w6692.own_ctrl = w6692_manager;
w6692.getinst = w6692_instance;
w6692.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0;
w6692.BPROTO.protocol[1] = ISDN_PID_L1_B_64TRANS |
ISDN_PID_L1_B_64HDLC;

View File

@ -1262,6 +1262,27 @@ MODULE_LICENSE("GPL");
#endif
#endif
static int
dte_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
mISDNinstance_t *inst = NULL;
x25_l3_t *l3;
u_long flags;
spin_lock_irqsave(&x25dte_obj.lock, flags);
list_for_each_entry(l3, &x25dte_obj.ilist, list) {
if (l3->inst.st == st) {
inst =&l3->inst;
break;
}
}
spin_unlock_irqrestore(&x25dte_obj.lock, flags);
if (inst)
return(-EBUSY);
return(new_l3(st, pid));
}
#ifdef OBSOLETE
static int
dte_manager(void *data, u_int prim, void *arg) {
mISDNinstance_t *inst = data;
@ -1331,6 +1352,7 @@ dte_manager(void *data, u_int prim, void *arg) {
}
return(0);
}
#endif
static int
x25_dte_init(void)
@ -1343,7 +1365,7 @@ x25_dte_init(void)
#endif
x25dte_obj.name = MName;
x25dte_obj.BPROTO.protocol[3] = ISDN_PID_L3_B_X25DTE;
x25dte_obj.own_ctrl = dte_manager;
x25dte_obj.getinst = dte_instance;
spin_lock_init(&x25dte_obj.lock);
INIT_LIST_HEAD(&x25dte_obj.ilist);
if ((err = mISDN_register(&x25dte_obj))) {

View File

@ -560,6 +560,33 @@ xhfc_l2l1(mISDNinstance_t *inst, struct sk_buff *skb)
return(ret);
}
static int
xhfc_instance(mISDNstack_t *st, mISDN_pid_t *pid)
{
xhfc_hw *hw;
mISDNinstance_t *inst = NULL;
u_long flags;
spin_lock_irqsave(&hw_mISDNObj.lock, flags);
list_for_each_entry(hw, &hw_mISDNObj.ilist, list) {
int i = 0;
while(i < MAX_CHAN) {
if (hw->chan[i].ch.inst.st == st) {
inst = &hw->chan[i].ch.inst;
break;
}
i++;
}
if (inst)
break;
}
spin_unlock_irqrestore(&hw_mISDNObj.lock, flags);
if (!inst)
return(-EINVAL);
return(mISDN_ctrl(st, MGR_REGLAYER | REQUEST, inst));
}
#ifdef OBSOLETE
static int
xhfc_manager(void *data, u_int prim, void *arg)
{
@ -2104,7 +2131,7 @@ xhfc_init(void)
INIT_LIST_HEAD(&hw_mISDNObj.ilist);
spin_lock_init(&hw_mISDNObj.lock);
hw_mISDNObj.name = DRIVER_NAME;
hw_mISDNObj.own_ctrl = xhfc_manager;
hw_mISDNObj.getinst = xhfc_instance;
hw_mISDNObj.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0 | ISDN_PID_L0_NT_S0;
hw_mISDNObj.DPROTO.protocol[1] = ISDN_PID_L1_TE_S0 | ISDN_PID_L1_NT_S0;

View File

@ -95,7 +95,7 @@
#define MGR_TIMER 0x0f8800
#define MGR_CONTROL 0x0fe100
#define MGR_STATUS 0x0fe200
#define MGR_HASPROTOCOL 0x0fe300
//#define MGR_HASPROTOCOL 0x0fe300
#define MGR_EVALSTACK 0x0fe400
#define MGR_GLOBALOPT 0x0fe500
#define MGR_SHORTSTATUS 0x0fe600
@ -338,9 +338,9 @@
#define ISDN_PID_L0_NT_UP2 0x00000400
#define ISDN_PID_L0_TE_E1 0x00000008
#define ISDN_PID_L0_NT_E1 0x00000800
#define ISDN_PID_L0_IP_S0 0x00000010
#define ISDN_PID_L0_IP_E1 0x00000020
#define ISDN_PID_L0_LOOP 0x00000030
#define ISDN_PID_L0_IP_S0 0x00100000
#define ISDN_PID_L0_IP_E1 0x00200000
#define ISDN_PID_L0_LOOP 0x00400000
#define ISDN_PID_L1_TE_S0 0x01000001
#define ISDN_PID_L1_NT_S0 0x01000100
#define ISDN_PID_L1_TE_U 0x01000002
@ -748,6 +748,7 @@ typedef struct _mISDNstack mISDNstack_t;
typedef struct _mISDNport mISDNport_t;
typedef struct _mISDNdevice mISDNdevice_t;
typedef int (ctrl_func_t)(void *, u_int, void *);
typedef int (inst_func_t)(mISDNstack_t *, mISDN_pid_t *);
typedef int (if_func_t)(mISDNinstance_t *, struct sk_buff *);
#define mISDN_HEAD_P(s) ((mISDN_head_t *)&s->cb[0])
@ -776,7 +777,7 @@ struct _mISDNobject {
int refcnt;
mISDN_pid_t DPROTO;
mISDN_pid_t BPROTO;
ctrl_func_t *own_ctrl;
inst_func_t *getinst;
struct list_head ilist;
spinlock_t lock;
struct module *owner;
@ -835,6 +836,7 @@ struct _mISDNstack {
mISDN_stPara_t para;
u_long status;
struct task_struct *thread;
int thread_id;
struct semaphore *notify;
wait_queue_head_t workq;
struct sk_buff_head msgq;
@ -851,6 +853,7 @@ struct _mISDNstack {
mISDNstack_t *clone;
mISDNstack_t *parent;
struct list_head childlist;
spinlock_t lock;
struct class_device class_dev;
/* temporary use */
mISDN_pid_t new_pid;