diff --git a/drivers/isdn/hardware/mISDN/core.c b/drivers/isdn/hardware/mISDN/core.c index 30bc309..611a448 100644 --- a/drivers/isdn/hardware/mISDN/core.c +++ b/drivers/isdn/hardware/mISDN/core.c @@ -106,7 +106,8 @@ mISDNd(void *data) hhe=mISDN_HEADEXT_P(skb); switch (hhe->addr) { case MGR_FUNCTION: - err=hhe->func.ctrl(hhe->data[0], hhe->prim, skb->data); + err = hhe->func.ctrl(hhe->data[0], hhe->prim, + skb->len ? skb->data : NULL); if (err) { printk(KERN_WARNING "mISDNd: addr(%x) prim(%x) failed err(%x)\n", hhe->addr, hhe->prim, err); @@ -423,7 +424,8 @@ set_stack_req(mISDNstack_t *st, mISDN_pid_t *pid) mISDN_pid_t *npid; u_char *pbuf = NULL; - skb = alloc_skb(sizeof(mISDN_pid_t) + pid->maxplen, GFP_ATOMIC); + if (!(skb = alloc_skb(sizeof(mISDN_pid_t) + pid->maxplen, GFP_ATOMIC))) + return(-ENOMEM); hhe = mISDN_HEADEXT_P(skb); hhe->prim = MGR_SETSTACK_NW | REQUEST; hhe->addr = MGR_FUNCTION; @@ -438,6 +440,26 @@ set_stack_req(mISDNstack_t *st, mISDN_pid_t *pid) return(0); } +static int +queue_ctrl_ready(mISDNstack_t *st, void *arg) +{ + struct sk_buff *skb; + mISDN_headext_t *hhe; + + if (!(skb = alloc_skb(4, GFP_ATOMIC))) + return(-ENOMEM); + if (arg) /* maybe changed for future enhancements */ + return(-EINVAL); + hhe = mISDN_HEADEXT_P(skb); + hhe->prim = MGR_CTRLREADY | INDICATION; + hhe->addr = MGR_FUNCTION; + hhe->data[0] = st; + hhe->func.ctrl = do_for_all_layers; + skb_queue_tail(&mISDN_thread.workq, skb); + wake_up_interruptible(&mISDN_thread.waitq); + return(0); +} + int mISDN_alloc_entity(int *entity) { @@ -540,7 +562,7 @@ static int central_manager(void *data, u_int prim, void *arg) { case MGR_ADDIF | REQUEST: return(add_if(data, prim, arg)); case MGR_CTRLREADY | INDICATION: - return(do_for_all_layers(st, prim, arg)); + return(queue_ctrl_ready(st, arg)); case MGR_ADDSTPARA | REQUEST: case MGR_CLRSTPARA | REQUEST: return(change_stack_para(st, prim, arg)); diff --git a/drivers/isdn/hardware/mISDN/core.h b/drivers/isdn/hardware/mISDN/core.h index d62294d..9cb4999 100644 --- a/drivers/isdn/hardware/mISDN/core.h +++ b/drivers/isdn/hardware/mISDN/core.h @@ -43,7 +43,7 @@ extern int get_stack_cnt(void); extern mISDNstack_t *get_stack4id(u_int); extern mISDNstack_t *new_stack(mISDNstack_t *, mISDNinstance_t *); extern int release_stack(mISDNstack_t *); -extern int do_for_all_layers(mISDNstack_t *, u_int, void *); +extern int do_for_all_layers(void *, u_int, void *); extern int change_stack_para(mISDNstack_t *, u_int, mISDN_stPara_t *); extern void release_stacks(mISDNobject_t *); extern int copy_pid(mISDN_pid_t *, mISDN_pid_t *, u_char *); diff --git a/drivers/isdn/hardware/mISDN/stack.c b/drivers/isdn/hardware/mISDN/stack.c index 2805566..1e6e1d4 100644 --- a/drivers/isdn/hardware/mISDN/stack.c +++ b/drivers/isdn/hardware/mISDN/stack.c @@ -303,8 +303,9 @@ release_layers(mISDNstack_t *st, u_int prim) } int -do_for_all_layers(mISDNstack_t *st, u_int prim, void *arg) +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;