diff --git a/drivers/isdn/hardware/mISDN/avm_fritz.c b/drivers/isdn/hardware/mISDN/avm_fritz.c index d261351..a0ae705 100644 --- a/drivers/isdn/hardware/mISDN/avm_fritz.c +++ b/drivers/isdn/hardware/mISDN/avm_fritz.c @@ -130,8 +130,7 @@ typedef struct hdlc_hw { typedef struct _fritzpnppci { - struct _fritzpnppci *prev; - struct _fritzpnppci *next; + struct list_head list; void *pdev; u_int type; u_int irq; @@ -410,7 +409,8 @@ hdlc_empty_fifo(bchannel_t *bch, int count) mISDN_debugprint(&bch->inst, "hdlc_empty_fifo: incoming packet too large"); return; } - ptr = (u_int *) p = bch->rx_buf + bch->rx_idx; + p = bch->rx_buf + bch->rx_idx; + ptr = (u_int *)p; bch->rx_idx += count; if (fc->type == AVM_FRITZ_PCIV2) { while (cnt < count) { @@ -1110,7 +1110,7 @@ release_card(fritzpnppci *card) mISDN_free_dch(&card->dch); fritz.ctrl(card->dch.inst.up.peer, MGR_DISCONNECT | REQUEST, &card->dch.inst.up); fritz.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL); - REMOVE_FROM_LISTBASE(card, ((fritzpnppci *)fritz.ilist)); + list_del(&card->list); unlock_dev(card); if (card->type == AVM_FRITZ_PNP) { pnp_disable_dev(card->pdev); @@ -1124,7 +1124,7 @@ release_card(fritzpnppci *card) static int fritz_manager(void *data, u_int prim, void *arg) { - fritzpnppci *card = fritz.ilist; + fritzpnppci *card; mISDNinstance_t *inst = data; struct sk_buff *skb; int channel = -1; @@ -1138,7 +1138,7 @@ fritz_manager(void *data, u_int prim, void *arg) { __FUNCTION__, prim, arg); return(-EINVAL); } - while(card) { + list_for_each_entry(card, &fritz.ilist, list) { if (&card->dch.inst == inst) { channel = 2; break; @@ -1151,7 +1151,6 @@ fritz_manager(void *data, u_int prim, void *arg) { channel = 1; break; } - card = card->next; } if (channel<0) { printk(KERN_WARNING "%s: no channel data %p prim %x arg %p\n", @@ -1245,7 +1244,7 @@ static int __devinit setup_instance(fritzpnppci *card) int i, err; mISDN_pid_t pid; - APPEND_TO_LIST(card, ((fritzpnppci *)fritz.ilist)); + list_add_tail(&card->list, &fritz.ilist); card->dch.debug = debug; lock_HW_init(&card->lock); card->dch.inst.lock = lock_dev; @@ -1274,7 +1273,7 @@ static int __devinit setup_instance(fritzpnppci *card) mISDN_free_dch(&card->dch); mISDN_free_bch(&card->bch[1]); mISDN_free_bch(&card->bch[0]); - REMOVE_FROM_LISTBASE(card, ((fritzpnppci *)fritz.ilist)); + list_del(&card->list); kfree(card); return(err); } @@ -1460,18 +1459,16 @@ static int __init Fritz_init(void) int err, pci_nr_found; printk(KERN_INFO "AVM Fritz PCI/PnP driver Rev. %s\n", mISDN_getrev(avm_fritz_rev)); - #ifdef MODULE fritz.owner = THIS_MODULE; #endif + INIT_LIST_HEAD(&fritz.ilist); fritz.name = FritzName; fritz.own_ctrl = fritz_manager; fritz.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0; fritz.BPROTO.protocol[1] = ISDN_PID_L1_B_64TRANS | ISDN_PID_L1_B_64HDLC; fritz.BPROTO.protocol[2] = ISDN_PID_L2_B_TRANS; - fritz.prev = NULL; - fritz.next = NULL; if ((err = mISDN_register(&fritz))) { printk(KERN_ERR "Can't register Fritz PCI error(%d)\n", err); return(err); @@ -1507,14 +1504,16 @@ static int __init Fritz_init(void) static void __exit Fritz_cleanup(void) { + fritzpnppci *card, *next; int err; + if ((err = mISDN_unregister(&fritz))) { printk(KERN_ERR "Can't unregister Fritz PCI error(%d)\n", err); } - while(fritz.ilist) { + list_for_each_entry_safe(card, next, &fritz.ilist, list) { printk(KERN_ERR "Fritz PCI card struct not empty refs %d\n", fritz.refcnt); - release_card(fritz.ilist); + release_card(card); } #if defined(CONFIG_PNP) pnp_unregister_driver(&fcpnp_driver); diff --git a/drivers/isdn/hardware/mISDN/capi.c b/drivers/isdn/hardware/mISDN/capi.c index f5708ee..9bcddf7 100644 --- a/drivers/isdn/hardware/mISDN/capi.c +++ b/drivers/isdn/hardware/mISDN/capi.c @@ -193,7 +193,7 @@ free_garbage(void) kmem_cache_free(mISDN_AppPlci_cp, item); break; case KM_DBG_TYP_NI: - printk(KERN_DEBUG "Ncci: NCCI(%x) state(%x) m.state(%x) aplci(%p)\n", + printk(KERN_DEBUG "Ncci: NCCI(%x) state(%lx) m.state(%x) aplci(%p)\n", kda->a.ni.addr, kda->a.ni.state, kda->a.ni.ncci_m.state, @@ -310,30 +310,29 @@ capi20_manager(void *data, u_int prim, void *arg) { mISDNinstance_t *inst = data; int found=0; PLInst_t *plink = NULL; - Controller_t *ctrl = (Controller_t *)capi_obj.ilist; + Controller_t *ctrl; if (CAPI_DBG_INFO & debug) printk(KERN_DEBUG "capi20_manager data:%p prim:%x arg:%p\n", data, prim, arg); if (!data) return(-EINVAL); - while(ctrl) { + list_for_each_entry(ctrl, &capi_obj.ilist, list) { if (&ctrl->inst == inst) { found++; break; } - plink = ctrl->linklist; - while(plink) { + list_for_each_entry(plink, &ctrl->linklist, list) { if (&plink->inst == inst) { found++; break; } - plink = plink->next; } if (found) break; plink = NULL; - ctrl = ctrl->next; } + if (&ctrl->list == &capi_obj.ilist) + ctrl = NULL; if (prim == (MGR_NEWLAYER | REQUEST)) { int ret = ControllerConstr(&ctrl, data, arg, &capi_obj); if (!ret) @@ -398,9 +397,7 @@ int Capi20Init(void) 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.prev = NULL; - capi_obj.next = NULL; - capi_obj.ilist = NULL; + INIT_LIST_HEAD(&capi_obj.ilist); if ((err = CapiNew())) return(err); if ((err = mISDN_register(&capi_obj))) { @@ -421,14 +418,14 @@ int Capi20Init(void) static void Capi20cleanup(void) { int err; - Controller_t *contr; + Controller_t *contr, *next; if ((err = mISDN_unregister(&capi_obj))) { printk(KERN_ERR "Can't unregister CAPI20 error(%d)\n", err); } - if (capi_obj.ilist) { + if (!list_empty(&capi_obj.ilist)) { printk(KERN_WARNING "mISDN controller list not empty\n"); - while((contr = capi_obj.ilist)) + list_for_each_entry_safe(contr, next, &capi_obj.ilist, list) ControllerDestr(contr); } #ifdef OLDCAPI_DRIVER_INTERFACE diff --git a/drivers/isdn/hardware/mISDN/contr.c b/drivers/isdn/hardware/mISDN/contr.c index f778e36..a173410 100644 --- a/drivers/isdn/hardware/mISDN/contr.c +++ b/drivers/isdn/hardware/mISDN/contr.c @@ -20,7 +20,7 @@ ControllerDestr(Controller_t *contr) spin_lock_irqsave(&contr->list_lock, flags); list_for_each_safe(item, next, &contr->Applications) { - ApplicationDestr((Application_t *)item, 3); + ApplicationDestr(list_entry(item, Application_t, head), 3); } if (contr->plcis) { Plci_t *plci = contr->plcis; @@ -46,7 +46,7 @@ ControllerDestr(Controller_t *contr) contr->plcis = NULL; } list_for_each_safe(item, next, &contr->SSProcesse) { - SSProcessDestr((SSProcess_t *)item); + SSProcessDestr(list_entry(item, SSProcess_t, head)); } #ifdef OLDCAPI_DRIVER_INTERFACE if (contr->ctrl) @@ -66,15 +66,15 @@ ControllerDestr(Controller_t *contr) inst->down.peer->obj->ctrl(inst->down.peer, MGR_DISCONNECT | REQUEST, &inst->down); } - while (contr->linklist) { - PLInst_t *plink = contr->linklist; - REMOVE_FROM_LISTBASE(plink, contr->linklist); + list_for_each_safe(item, next, &contr->linklist) { + PLInst_t *plink = list_entry(item, PLInst_t, list); + list_del(&plink->list); kfree(plink); } if (contr->entity != MISDN_ENTITY_NONE) inst->obj->ctrl(inst, MGR_DELENTITY | REQUEST, (void *)contr->entity); inst->obj->ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL); - REMOVE_FROM_LISTBASE(contr, ((Controller_t *)inst->obj->ilist)); + list_del(&contr->list); spin_unlock_irqrestore(&contr->list_lock, flags); kfree(contr); } @@ -116,8 +116,13 @@ ControllerRun(Controller_t *contr) pidmask.protocol[1] = 0x03ff; pidmask.protocol[2] = 0x1fff; pidmask.protocol[3] = 0x00ff; - plink = contr->linklist; - ret = plink->inst.obj->ctrl(plink->st, MGR_EVALSTACK | REQUEST, &pidmask); + if (list_empty(&contr->linklist)) { + int_error(); + ret = -EINVAL; + } else { + plink = list_entry(contr->linklist.next, PLInst_t, list); + ret = plink->inst.obj->ctrl(plink->st, MGR_EVALSTACK | REQUEST, &pidmask); + } if (ret) { /* Fallback on error, minimum set */ int_error(); @@ -510,13 +515,25 @@ ControllerPutStatus(Controller_t *contr, char *msg) int ControllerConstr(Controller_t **contr_p, mISDNstack_t *st, mISDN_pid_t *pid, mISDNobject_t *ocapi) { - Controller_t *contr; - int retval; - mISDNstack_t *cst; - PLInst_t *plink; + struct list_head *head; + Controller_t *contr; + int retval; + mISDNstack_t *cst; + PLInst_t *plink; if (!st) return(-EINVAL); + if (list_empty(&st->childlist)) { + if ((st->id & FLG_CLONE_STACK) && + (st->childlist.prev != &st->childlist)) { + head = st->childlist.prev; + } else { + printk(KERN_ERR "%s: invalid empty childlist (no clone) stid(%x) childlist(%p<-%p->%p)\n", + __FUNCTION__, st->id, st->childlist.prev, &st->childlist, st->childlist.next); + return(-EINVAL); + } + } else + head = &st->childlist; if (!pid) return(-EINVAL); contr = kmalloc(sizeof(Controller_t), GFP_KERNEL); @@ -525,6 +542,7 @@ ControllerConstr(Controller_t **contr_p, mISDNstack_t *st, mISDN_pid_t *pid, mIS memset(contr, 0, sizeof(Controller_t)); INIT_LIST_HEAD(&contr->Applications); INIT_LIST_HEAD(&contr->SSProcesse); + INIT_LIST_HEAD(&contr->linklist); spin_lock_init(&contr->list_lock); spin_lock_init(&contr->id_lock); contr->next_id = 1; @@ -538,11 +556,8 @@ ControllerConstr(Controller_t **contr_p, mISDNstack_t *st, mISDN_pid_t *pid, mIS } memset(contr->ctrl, 0, sizeof(struct capi_ctr)); #endif - cst = st->child; - while(cst) { + list_for_each_entry(cst, head, list) contr->nr_bc++; - cst = cst->next; - } if (!contr->nr_bc) { printk(KERN_ERR "no bchannels\n"); ControllerDestr(contr); @@ -571,8 +586,7 @@ ControllerConstr(Controller_t **contr_p, mISDNstack_t *st, mISDN_pid_t *pid, mIS ControllerDestr(contr); return(-ENOPROTOOPT); } - cst = st->child; - while(cst) { + list_for_each_entry(cst, head, list) { if (!(plink = kmalloc(sizeof(PLInst_t), GFP_KERNEL))) { printk(KERN_ERR "no mem for PLinst\n"); int_error(); @@ -585,10 +599,9 @@ ControllerConstr(Controller_t **contr_p, mISDNstack_t *st, mISDN_pid_t *pid, mIS mISDN_init_instance(&plink->inst, ocapi, plink); plink->inst.pid.layermask |= ISDN_LAYER(4); plink->inst.down.stat = IF_NOACTIV; - APPEND_TO_LIST(plink, contr->linklist); - cst = cst->next; + list_add_tail(&plink->list, &contr->linklist); } - APPEND_TO_LIST(contr, ocapi->ilist); + list_add_tail(&contr->list, &ocapi->ilist); contr->entity = MISDN_ENTITY_NONE; retval = ocapi->ctrl(&contr->inst, MGR_NEWENTITY | REQUEST, NULL); if (retval) { @@ -639,26 +652,23 @@ ControllerSelChannel(Controller_t *contr, u_int channel) channel_info_t ci; int ret; - if (!contr->linklist) { + if (list_empty(&contr->linklist)) { int_errtxt("no linklist for controller(%x)", contr->addr); return(NULL); } ci.channel = channel; ci.st.p = NULL; - ret = contr->inst.obj->ctrl(contr->inst.st, MGR_SELCHANNEL | REQUEST, - &ci); + ret = contr->inst.obj->ctrl(contr->inst.st, MGR_SELCHANNEL | REQUEST, &ci); if (ret) { int_errtxt("MGR_SELCHANNEL ret(%d)", ret); return(NULL); } cst = ci.st.p; - plink = contr->linklist; - while(plink) { + list_for_each_entry(plink, &contr->linklist, list) { if (cst == plink->st) - break; - plink = plink->next; + return(plink); } - return(plink); + return(NULL); } int diff --git a/drivers/isdn/hardware/mISDN/core.c b/drivers/isdn/hardware/mISDN/core.c index 0b4e158..d49f1c9 100644 --- a/drivers/isdn/hardware/mISDN/core.c +++ b/drivers/isdn/hardware/mISDN/core.c @@ -19,10 +19,11 @@ #include #endif -static char *mISDN_core_revision = "$Revision$"; +static char *mISDN_core_revision = "$Revision$"; + +LIST_HEAD(mISDN_objectlist); +rwlock_t mISDN_objects_lock = RW_LOCK_UNLOCKED; -mISDNobject_t *mISDN_objects = NULL; -rwlock_t mISDN_objects_lock = RW_LOCK_UNLOCKED; int core_debug; static u_char entityarray[MISDN_MAX_ENTITY/8]; @@ -153,14 +154,13 @@ get_object(int id) { mISDNobject_t *obj; read_lock(&mISDN_objects_lock); - obj = mISDN_objects; - while(obj) { - if (obj->id == id) - break; - obj = obj->next; - } + list_for_each_entry(obj, &mISDN_objectlist, list) + if (obj->id == id) { + read_unlock(&mISDN_objects_lock); + return(obj); + } read_unlock(&mISDN_objects_lock); - return(obj); + return(NULL); } static mISDNobject_t * @@ -169,17 +169,17 @@ find_object(int protocol) { int err; read_lock(&mISDN_objects_lock); - obj = mISDN_objects; - while (obj) { + list_for_each_entry(obj, &mISDN_objectlist, list) { err = obj->own_ctrl(NULL, MGR_HASPROTOCOL | REQUEST, &protocol); if (!err) - break; + goto unlock; if (err != -ENOPROTOOPT) { if (0 == mISDN_HasProtocol(obj, protocol)) - break; + goto unlock; } - obj = obj->next; } + obj = NULL; +unlock: read_unlock(&mISDN_objects_lock); return(obj); } @@ -220,26 +220,16 @@ find_object_module(int protocol) { static void remove_object(mISDNobject_t *obj) { - mISDNstack_t *st = mISDN_stacklist; - mISDNlayer_t *layer; - mISDNinstance_t *inst, *tmp; + mISDNstack_t *st, *nst; + mISDNlayer_t *layer, *nl; + mISDNinstance_t *inst; - while (st) { - layer = st->lstack; - while(layer) { + list_for_each_entry_safe(st, nst, &mISDN_stacklist, list) { + list_for_each_entry_safe(layer, nl, &st->layerlist, list) { inst = layer->inst; - while (inst) { - if (inst->obj == obj) { - tmp = inst->next; - inst->obj->own_ctrl(st, MGR_RELEASE - | INDICATION, inst); - inst = tmp; - } else - inst = inst->next; - } - layer = layer->next; + if (inst && inst->obj == obj) + inst->obj->own_ctrl(st, MGR_RELEASE | INDICATION, inst); } - st = st->next; } } @@ -296,7 +286,7 @@ get_next_instance(mISDNstack_t *st, mISDN_pid_t *pid) static int sel_channel(mISDNstack_t *st, channel_info_t *ci) { - int err = -EINVAL; + int err = -EINVAL; if (!ci) return(err); @@ -314,20 +304,30 @@ sel_channel(mISDNstack_t *st, channel_info_t *ci) printk(KERN_WARNING "%s: no mgr st(%p)\n", __FUNCTION__, st); } if (err) { - mISDNstack_t *cst = st->child; + mISDNstack_t *cst; u_int nr = 0; ci->st.p = NULL; if (!(ci->channel & (~CHANNEL_NUMBER))) { /* only number is set */ - while(cst) { + struct list_head *head; + if (list_empty(&st->childlist)) { + if ((st->id & FLG_CLONE_STACK) && + (st->childlist.prev != &st->childlist)) { + head = st->childlist.prev; + } else { + printk(KERN_WARNING "%s: invalid empty childlist (no clone) stid(%x) childlist(%p<-%p->%p)\n", + __FUNCTION__, st->id, st->childlist.prev, &st->childlist, st->childlist.next); + return(err); + } + } else + head = &st->childlist; + list_for_each_entry(cst, head, list) { nr++; if (nr == (ci->channel & 3)) { ci->st.p = cst; - err = 0; - break; + return(0); } - cst = cst->next; } } } @@ -363,7 +363,10 @@ add_if(mISDNinstance_t *inst, u_int prim, mISDNif_t *hif) { myif = &inst->up; } else return(-EINVAL); - APPEND_TO_LIST(hif, myif); + while(myif->clone) + myif = myif->clone; + myif->clone = hif; + hif->predecessor = myif; inst->obj->own_ctrl(inst, prim, hif); return(0); } @@ -567,7 +570,7 @@ int mISDN_register(mISDNobject_t *obj) { return(-EINVAL); write_lock_irqsave(&mISDN_objects_lock, flags); obj->id = obj_id++; - APPEND_TO_LIST(obj, mISDN_objects); + list_add_tail(&obj->list, &mISDN_objectlist); write_unlock_irqrestore(&mISDN_objects_lock, flags); obj->ctrl = central_manager; // register_prop @@ -592,10 +595,11 @@ int mISDN_unregister(mISDNobject_t *obj) { else remove_object(obj); write_lock_irqsave(&mISDN_objects_lock, flags); - REMOVE_FROM_LISTBASE(obj, mISDN_objects); + list_del(&obj->list); write_unlock_irqrestore(&mISDN_objects_lock, flags); if (core_debug & DEBUG_CORE_FUNC) - printk(KERN_DEBUG "mISDN_unregister: mISDN_objects(%p)\n", mISDN_objects); + printk(KERN_DEBUG "mISDN_unregister: mISDN_objectlist(%p<-%p->%p)\n", + mISDN_objectlist.prev, &mISDN_objectlist, mISDN_objectlist.next); return(0); } @@ -628,23 +632,21 @@ mISDNInit(void) void mISDN_cleanup(void) { DECLARE_MUTEX_LOCKED(sem); - mISDNstack_t *st; + mISDNstack_t *st, *nst; free_mISDNdev(); - if (mISDN_objects) { + if (!list_empty(&mISDN_objectlist)) { printk(KERN_WARNING "mISDNcore mISDN_objects not empty\n"); } - if (mISDN_stacklist) { + if (!list_empty(&mISDN_stacklist)) { printk(KERN_WARNING "mISDNcore mISDN_stacklist not empty\n"); - st = mISDN_stacklist; - while (st) { - printk(KERN_WARNING "mISDNcore st %x in list\n", + list_for_each_entry_safe(st, nst, &mISDN_stacklist, list) { + printk(KERN_WARNING "mISDNcore st %x still in list\n", st->id); - if (st == st->next) { + if (list_empty(&st->list)) { printk(KERN_WARNING "mISDNcore st == next\n"); break; } - st = st->next; } } if (mISDN_thread.thread) { diff --git a/drivers/isdn/hardware/mISDN/core.h b/drivers/isdn/hardware/mISDN/core.h index 869fc23..8b82d89 100644 --- a/drivers/isdn/hardware/mISDN/core.h +++ b/drivers/isdn/hardware/mISDN/core.h @@ -37,8 +37,8 @@ extern int free_device(mISDNdevice_t *dev); /* from mISDN_stack.c */ -extern mISDNstack_t *mISDN_stacklist; -extern mISDNinstance_t *mISDN_instlist; +extern struct list_head mISDN_stacklist; +extern struct list_head mISDN_instlist; extern void get_stack_info(iframe_t *); extern int get_stack_cnt(void); @@ -57,7 +57,7 @@ extern mISDNinstance_t *get_instance(mISDNstack_t *, int, int); /* from mISDN_core.c */ -extern mISDNobject_t *mISDN_objects; +extern struct list_head mISDN_objectlist; extern int core_debug; extern int register_layer(mISDNstack_t *, mISDNinstance_t *); diff --git a/drivers/isdn/hardware/mISDN/dsp.h b/drivers/isdn/hardware/mISDN/dsp.h index 7d5863d..7f51b69 100644 --- a/drivers/isdn/hardware/mISDN/dsp.h +++ b/drivers/isdn/hardware/mISDN/dsp.h @@ -78,24 +78,22 @@ extern u8 silence; /* all members within a conference (this is linked 1:1 with the dsp) */ struct _dsp; typedef struct _conf_member { - struct _conf_member *prev; - struct _conf_member *next; - struct _dsp *dsp; + struct list_head list; + struct _dsp *dsp; } conf_member_t; /* the list of all conferences */ typedef struct _conference { - struct _conference *prev; - struct _conference *next; - u32 id; /* all cmx stacks with the same ID are connected */ - conf_member_t *mlist; - int software; /* conf is processed by software */ - int hardware; /* conf is processed by hardware */ + struct list_head list; + u32 id; /* all cmx stacks with the same ID are connected */ + struct list_head mlist; + int software; /* conf is processed by software */ + int hardware; /* conf is processed by hardware */ //#ifndef AUTOJITTER - int largest; /* largest frame received in conf's life. */ + int largest; /* largest frame received in conf's life. */ //#endif - int W_min, W_max; /* min/maximum rx-write pointer of members */ - s32 conf_buff[CMX_BUFF_SIZE]; + int W_min, W_max; /* min/maximum rx-write pointer of members */ + s32 conf_buff[CMX_BUFF_SIZE]; } conference_t; extern mISDNobject_t dsp_obj; @@ -148,8 +146,7 @@ struct dsp_features { }; typedef struct _dsp { - struct _dsp *prev; - struct _dsp *next; + struct list_head list; mISDNinstance_t inst; int b_active; int echo; /* echo is done by software */ @@ -205,7 +202,7 @@ typedef struct _dsp { extern void dsp_change_volume(struct sk_buff *skb, int volume); -extern conference_t *Conf_list; +extern struct list_head Conf_list; extern void dsp_cmx_debug(dsp_t *dsp); extern void dsp_cmx_hardware(conference_t *conf, dsp_t *dsp); extern int dsp_cmx_conf(dsp_t *dsp, u32 conf_id); diff --git a/drivers/isdn/hardware/mISDN/dsp_cmx.c b/drivers/isdn/hardware/mISDN/dsp_cmx.c index f55326d..7ee43be 100644 --- a/drivers/isdn/hardware/mISDN/dsp_cmx.c +++ b/drivers/isdn/hardware/mISDN/dsp_cmx.c @@ -149,7 +149,7 @@ //#define CMX_DEBUG /* massive read/write pointer output */ extern mISDN_HWlock_t dsp_lock; -conference_t *Conf_list = NULL; +LIST_HEAD(Conf_list); /* * debug cmx memory structure @@ -162,8 +162,7 @@ dsp_cmx_debug(dsp_t *dsp) dsp_t *odsp; printk(KERN_DEBUG "-----Current DSP\n"); - odsp = (dsp_t *)dsp_obj.ilist; - while(odsp) + list_for_each_entry(odsp, &dsp_obj.ilist, list) { printk(KERN_DEBUG "* %s echo=%d txmix=%d", odsp->inst.name, odsp->echo, odsp->tx_mix); if (odsp->conf) @@ -171,21 +170,16 @@ dsp_cmx_debug(dsp_t *dsp) if (dsp == odsp) printk(" *this*"); printk("\n"); - odsp = odsp->next; } printk(KERN_DEBUG "-----Current Conf:\n"); - conf = Conf_list; - while(conf) + list_for_each_entry(conf, &Conf_list, list) { printk(KERN_DEBUG "* Conf %d (0x%x)\n", conf->id, (u32)conf); - member = conf->mlist; - while(member) + list_for_each_entry(member, &conf->mlist, list) { printk(KERN_DEBUG " - member = %s (slot_tx %d, bank_tx %d, slot_rx %d, bank_rx %d hfc_conf %d)%s\n", member->dsp->inst.name, member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx, member->dsp->hfc_conf, (member->dsp==dsp)?" *this*":""); - member = member->next; } - conf = conf->next; } printk(KERN_DEBUG "-----end\n"); } @@ -205,12 +199,9 @@ static conference_t } /* search conference */ - conf = Conf_list; - while(conf) { + list_for_each_entry(conf, &Conf_list, list) if (conf->id == id) return(conf); - conf = conf->next; - } return(NULL); } @@ -254,10 +245,10 @@ dsp_cmx_add_conf_member(dsp_t *dsp, conference_t *conf) dsp->W_rx = conf->W_max; dsp->R_rx = conf->W_max; - APPEND_TO_LIST(member, ((conf_member_t *)conf->mlist)); + list_add_tail(&member->list, &conf->mlist); /* zero conf-buffer if we change from 2 to 3 members */ - if (conf->mlist->next) if (!conf->mlist->next->next) + if (3 == count_list_member(&conf->mlist)) memset(conf->conf_buff, 0, sizeof(conf->conf_buff)); dsp->conf = conf; @@ -287,33 +278,28 @@ dsp_cmx_del_conf_member(dsp_t *dsp) return(-EINVAL); } - member = dsp->conf->mlist; - if (!member) { + if (list_empty(&dsp->conf->mlist)) { printk(KERN_WARNING "%s: dsp has linked an empty conf.\n", __FUNCTION__); return(-EINVAL); } /* find us in conf */ - while(member) { - if (member->dsp == dsp) - break; - member = member->next; - } - if (!member) { - printk(KERN_WARNING "%s: dsp is not present in its own conf_meber list.\n", - __FUNCTION__); - return(-EINVAL); + list_for_each_entry(member, &dsp->conf->mlist, list) { + if (member->dsp == dsp) { + list_del(&member->list); + dsp->conf = NULL; + dsp->member = NULL; + unlock_HW(&dsp_lock); + vfree(member); + lock_HW(&dsp_lock, 0); + return(0); + } } + printk(KERN_WARNING "%s: dsp is not present in its own conf_meber list.\n", + __FUNCTION__); - REMOVE_FROM_LISTBASE(member, ((conf_member_t *)dsp->conf->mlist)); - dsp->conf = NULL; - dsp->member = NULL; - unlock_HW(&dsp_lock); - vfree(member); - lock_HW(&dsp_lock, 0); - - return(0); + return(-EINVAL); } @@ -339,9 +325,10 @@ static conference_t } lock_HW(&dsp_lock, 0); memset(conf, 0, sizeof(conference_t)); + INIT_LIST_HEAD(&conf->mlist); conf->id = id; - APPEND_TO_LIST(conf, ((conference_t *)Conf_list)); + list_add_tail(&conf->list, &Conf_list); return(conf); } @@ -359,13 +346,12 @@ dsp_cmx_del_conf(conference_t *conf) return(-EINVAL); } - if (conf->mlist) { + if (!list_empty(&conf->mlist)) { printk(KERN_WARNING "%s: conf not empty.\n", __FUNCTION__); return(-EINVAL); } - - REMOVE_FROM_LISTBASE(conf, ((conference_t *)Conf_list)); + list_del(&conf->list); unlock_HW(&dsp_lock); vfree(conf); lock_HW(&dsp_lock, 0); @@ -409,11 +395,11 @@ dsp_cmx_hw_message(dsp_t *dsp, u32 message, u32 param1, u32 param2, u32 param3, void dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) { - conf_member_t *member; + conf_member_t *member, *nextm; int memb = 0, i, ii, i1, i2; int freeunits[8]; u_char freeslots[256]; - int same_hfc = -1, current_conf = -1, all_conf = 1; + int same_hfc = -1, same_pcm = -1, current_conf = -1, all_conf = 1; /* dsp gets updated (no conf) */ //printk("-----1\n"); @@ -451,18 +437,22 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) if (dsp_debug & DEBUG_DSP_CMX) printk(KERN_DEBUG "%s checking conference %d\n", __FUNCTION__, conf->id); //printk("-----5\n"); - - member = conf->mlist; + + if (list_empty(&conf->mlist)) { + printk(KERN_ERR "%s: conference whithout members\n", __FUNCTION__); + return; + } + member = list_entry(conf->mlist.next, conf_member_t, list); same_hfc = member->dsp->features.hfc_id; + same_pcm = member->dsp->features.pcm_id; /* check all members in our conference */ - while (member) { + list_for_each_entry(member, &conf->mlist, list) { /* check if member uses mixing */ if (member->dsp->tx_mix) { if (dsp_debug & DEBUG_DSP_CMX) printk(KERN_DEBUG "%s dsp %s cannot form a conf, because tx_mix is turned on\n", __FUNCTION__, member->dsp->inst.name); conf_software: - member = conf->mlist; - while (member) { + list_for_each_entry(member, &conf->mlist, list) { dsp = member->dsp; /* remove HFC conference if enabled */ if (dsp->hfc_conf >= 0) { @@ -481,7 +471,6 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) dsp->pcm_slot_rx = -1; dsp->pcm_bank_rx = -1; } - member = member->next; } conf->hardware = 0; conf->software = 1; @@ -517,9 +506,10 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) goto conf_software; } /* check if relations are on the same PCM bus */ - if (member->dsp->features.pcm_id != conf->mlist->dsp->features.pcm_id) { + if (member->dsp->features.pcm_id != same_pcm) { if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s dsp %s cannot form a conf, because dsp is on a different PCM bus than the first dsp\n", __FUNCTION__, member->dsp->inst.name); + printk(KERN_DEBUG "%s dsp %s cannot form a conf, because dsp is on a different PCM bus than the first dsp\n", + __FUNCTION__, member->dsp->inst.name); goto conf_software; } /* determine if members are on the same hfc chip */ @@ -532,7 +522,6 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) if (member->dsp->hfc_conf < 0) all_conf = 0; - member = member->next; memb++; } @@ -546,7 +535,8 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) printk(KERN_DEBUG "%s conf %d cannot form a HW conference, because dsp is alone\n", __FUNCTION__, conf->id); conf->hardware = 0; conf->software = 1; - dsp = conf->mlist->dsp; + member = list_entry(conf->mlist.next, conf_member_t, list); + dsp = member->dsp; goto one_member; } @@ -557,7 +547,8 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) /* if we have only two members */ if (memb == 2) { - member = conf->mlist; + member = list_entry(conf->mlist.next, conf_member_t, list); + nextm = list_entry(member->list.next, conf_member_t, list); /* remove HFC conference if enabled */ if (member->dsp->hfc_conf >= 0) { if (dsp_debug & DEBUG_DSP_CMX) @@ -565,39 +556,40 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) dsp_cmx_hw_message(member->dsp, HW_CONF_SPLIT, 0, 0, 0, 0); member->dsp->hfc_conf = -1; } - if (member->next->dsp->hfc_conf >= 0) { + if (nextm->dsp->hfc_conf >= 0) { if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s removing %s from HFC conf %d because two parties require only a PCM slot\n", __FUNCTION__, member->next->dsp->inst.name, member->next->dsp->hfc_conf); - dsp_cmx_hw_message(member->next->dsp, HW_CONF_SPLIT, 0, 0, 0, 0); - member->next->dsp->hfc_conf = -1; + printk(KERN_DEBUG "%s removing %s from HFC conf %d because two parties require only a PCM slot\n", __FUNCTION__, nextm->dsp->inst.name, nextm->dsp->hfc_conf); + dsp_cmx_hw_message(nextm->dsp, HW_CONF_SPLIT, 0, 0, 0, 0); + nextm->dsp->hfc_conf = -1; } /* if members have two banks (and not on the same chip) */ if (member->dsp->features.pcm_banks>1 - && member->next->dsp->features.pcm_banks>1 - && member->dsp->features.pcm_id!=member->next->dsp->features.pcm_id) { + && nextm->dsp->features.pcm_banks>1 + && member->dsp->features.pcm_id!=nextm->dsp->features.pcm_id) { /* if both members have same slots with crossed banks */ if (member->dsp->pcm_slot_tx>=0 && member->dsp->pcm_slot_rx>=0 - && member->next->dsp->pcm_slot_tx>=0 - && member->next->dsp->pcm_slot_rx>=0 - && member->next->dsp->pcm_slot_tx==member->dsp->pcm_slot_rx - && member->next->dsp->pcm_slot_rx==member->dsp->pcm_slot_tx - && member->next->dsp->pcm_slot_tx==member->dsp->pcm_slot_tx + && nextm->dsp->pcm_slot_tx>=0 + && nextm->dsp->pcm_slot_rx>=0 + && nextm->dsp->pcm_slot_tx==member->dsp->pcm_slot_rx + && nextm->dsp->pcm_slot_rx==member->dsp->pcm_slot_tx + && nextm->dsp->pcm_slot_tx==member->dsp->pcm_slot_tx && member->dsp->pcm_bank_tx!=member->dsp->pcm_bank_rx - && member->next->dsp->pcm_bank_tx!=member->next->dsp->pcm_bank_rx) { + && nextm->dsp->pcm_bank_tx!=nextm->dsp->pcm_bank_rx) { /* all members have same slot */ if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s dsp %s & %s stay joined on PCM slot %d bank %d (TX) bank %d (RX) (on different chips)\n", __FUNCTION__, member->dsp->inst.name, member->next->dsp->inst.name, member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx, member->dsp->pcm_bank_rx); + printk(KERN_DEBUG "%s dsp %s & %s stay joined on PCM slot %d bank %d (TX) bank %d (RX) (on different chips)\n", __FUNCTION__, + member->dsp->inst.name, nextm->dsp->inst.name, + member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx, member->dsp->pcm_bank_rx); conf->hardware = 0; conf->software = 1; return; } /* find a new slot */ memset(freeslots, 1, sizeof(freeslots)); - dsp = (dsp_t *)dsp_obj.ilist; - while(dsp) { + list_for_each_entry(dsp, &dsp_obj.ilist, list) { if (dsp!=member->dsp - && dsp!=member->next->dsp + && dsp!=nextm->dsp && member->dsp->features.pcm_id==dsp->features.pcm_id) { if (dsp->pcm_slot_rx>=0 && dsp->pcm_slot_rxpcm_slot_txpcm_slot_rx] = 0; } - dsp = dsp->next; } i = 0; ii = member->dsp->features.pcm_slots; @@ -617,23 +608,27 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) } if (i == ii) { if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s no slot available for %s & %s\n", __FUNCTION__, member->dsp->inst.name, member->next->dsp->inst.name); + printk(KERN_DEBUG "%s no slot available for %s & %s\n", __FUNCTION__, + member->dsp->inst.name, nextm->dsp->inst.name); /* no more slots available */ goto conf_software; } /* assign free slot */ member->dsp->pcm_slot_tx = i; member->dsp->pcm_slot_rx = i; - member->next->dsp->pcm_slot_tx = i; - member->next->dsp->pcm_slot_rx = i; + nextm->dsp->pcm_slot_tx = i; + nextm->dsp->pcm_slot_rx = i; member->dsp->pcm_bank_rx = 0; member->dsp->pcm_bank_tx = 1; - member->next->dsp->pcm_bank_rx = 1; - member->next->dsp->pcm_bank_tx = 0; + nextm->dsp->pcm_bank_rx = 1; + nextm->dsp->pcm_bank_tx = 0; if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s adding %s & %s to new PCM slot %d (TX and RX on different chips) because both members have not same slots\n", __FUNCTION__, member->dsp->inst.name, member->next->dsp->inst.name, member->dsp->pcm_slot_tx); - dsp_cmx_hw_message(member->dsp, HW_PCM_CONN, member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx); - dsp_cmx_hw_message(member->next->dsp, HW_PCM_CONN, member->next->dsp->pcm_slot_tx, member->next->dsp->pcm_bank_tx, member->next->dsp->pcm_slot_rx, member->next->dsp->pcm_bank_rx); + printk(KERN_DEBUG "%s adding %s & %s to new PCM slot %d (TX and RX on different chips) because both members have not same slots\n", __FUNCTION__, + member->dsp->inst.name, nextm->dsp->inst.name, member->dsp->pcm_slot_tx); + dsp_cmx_hw_message(member->dsp, HW_PCM_CONN, member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx, + member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx); + dsp_cmx_hw_message(nextm->dsp, HW_PCM_CONN, nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx, + nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx); conf->hardware = 1; conf->software = 0; return; @@ -642,28 +637,28 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) /* if both members have different crossed slots */ if (member->dsp->pcm_slot_tx>=0 && member->dsp->pcm_slot_rx>=0 - && member->next->dsp->pcm_slot_tx>=0 - && member->next->dsp->pcm_slot_rx>=0 - && member->next->dsp->pcm_slot_tx==member->dsp->pcm_slot_rx - && member->next->dsp->pcm_slot_rx==member->dsp->pcm_slot_tx + && nextm->dsp->pcm_slot_tx>=0 + && nextm->dsp->pcm_slot_rx>=0 + && nextm->dsp->pcm_slot_tx==member->dsp->pcm_slot_rx + && nextm->dsp->pcm_slot_rx==member->dsp->pcm_slot_tx && member->dsp->pcm_slot_tx!=member->dsp->pcm_slot_rx && member->dsp->pcm_bank_tx==0 && member->dsp->pcm_bank_rx==0 - && member->next->dsp->pcm_bank_tx==0 - && member->next->dsp->pcm_bank_rx==0) { + && nextm->dsp->pcm_bank_tx==0 + && nextm->dsp->pcm_bank_rx==0) { /* all members have same slot */ if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s dsp %s & %s stay joined on PCM slot %d (TX) %d (RX) on same chip or one bank PCM)\n", __FUNCTION__, member->dsp->inst.name, member->next->dsp->inst.name, member->dsp->pcm_slot_tx, member->dsp->pcm_slot_rx); + printk(KERN_DEBUG "%s dsp %s & %s stay joined on PCM slot %d (TX) %d (RX) on same chip or one bank PCM)\n", __FUNCTION__, + member->dsp->inst.name, nextm->dsp->inst.name, member->dsp->pcm_slot_tx, member->dsp->pcm_slot_rx); conf->hardware = 0; conf->software = 1; return; } /* find two new slot */ memset(freeslots, 1, sizeof(freeslots)); - dsp = (dsp_t *)dsp_obj.ilist; - while(dsp) { + list_for_each_entry(dsp, &dsp_obj.ilist, list) { if (dsp!=member->dsp - && dsp!=member->next->dsp + && dsp!=nextm->dsp && member->dsp->features.pcm_id==dsp->features.pcm_id) { if (dsp->pcm_slot_rx>=0 && dsp->pcm_slot_rxpcm_slot_txpcm_slot_rx] = 0; } - dsp = dsp->next; } i1 = 0; ii = member->dsp->features.pcm_slots; @@ -683,7 +677,8 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) } if (i1 == ii) { if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s no slot available for %s & %s\n", __FUNCTION__, member->dsp->inst.name, member->next->dsp->inst.name); + printk(KERN_DEBUG "%s no slot available for %s & %s\n", __FUNCTION__, + member->dsp->inst.name, nextm->dsp->inst.name); /* no more slots available */ goto conf_software; } @@ -695,23 +690,26 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) } if (i2 == ii) { if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s no slot available for %s & %s\n", __FUNCTION__, member->dsp->inst.name, member->next->dsp->inst.name); + printk(KERN_DEBUG "%s no slot available for %s & %s\n", __FUNCTION__, + member->dsp->inst.name, nextm->dsp->inst.name); /* no more slots available */ goto conf_software; } /* assign free slots */ member->dsp->pcm_slot_tx = i1; member->dsp->pcm_slot_rx = i2; - member->next->dsp->pcm_slot_tx = i2; - member->next->dsp->pcm_slot_rx = i1; + nextm->dsp->pcm_slot_tx = i2; + nextm->dsp->pcm_slot_rx = i1; member->dsp->pcm_bank_rx = 0; member->dsp->pcm_bank_tx = 0; - member->next->dsp->pcm_bank_rx = 0; - member->next->dsp->pcm_bank_tx = 0; + nextm->dsp->pcm_bank_rx = 0; + nextm->dsp->pcm_bank_tx = 0; if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s adding %s & %s to new PCM slot %d (TX) %d (RX) on same chip or one bank PCM) because both members have not crossed slots\n", __FUNCTION__, member->dsp->inst.name, member->next->dsp->inst.name, member->dsp->pcm_slot_tx, member->dsp->pcm_slot_rx); + printk(KERN_DEBUG "%s adding %s & %s to new PCM slot %d (TX) %d (RX) on same chip or one bank PCM) because both members have not crossed slots\n", __FUNCTION__, + member->dsp->inst.name, nextm->dsp->inst.name, member->dsp->pcm_slot_tx, + member->dsp->pcm_slot_rx); dsp_cmx_hw_message(member->dsp, HW_PCM_CONN, member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx); - dsp_cmx_hw_message(member->next->dsp, HW_PCM_CONN, member->next->dsp->pcm_slot_tx, member->next->dsp->pcm_bank_tx, member->next->dsp->pcm_slot_rx, member->next->dsp->pcm_bank_rx); + dsp_cmx_hw_message(nextm->dsp, HW_PCM_CONN, nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx, nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx); conf->hardware = 1; conf->software = 0; return; @@ -725,7 +723,8 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) /* if not the same HFC chip */ if (same_hfc < 0) { if (dsp_debug & DEBUG_DSP_CMX) - printk(KERN_DEBUG "%s conference %d cannot be formed, because members are on different chips or not on HFC chip\n", __FUNCTION__, conf->id); + printk(KERN_DEBUG "%s conference %d cannot be formed, because members are on different chips or not on HFC chip\n", + __FUNCTION__, conf->id); goto conf_software; } @@ -737,17 +736,14 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) */ if (current_conf >= 0) { join_members: - member = conf->mlist; - while (member) { + list_for_each_entry(member, &conf->mlist, list) { /* join to current conference */ if (member->dsp->hfc_conf == current_conf) { - member = member->next; continue; } /* get a free timeslot first */ memset(freeslots, 1, sizeof(freeslots)); - dsp = (dsp_t *)dsp_obj.ilist; - while(dsp) { + list_for_each_entry(dsp, &dsp_obj.ilist, list) { /* not checking current member, because * slot will be overwritten. */ @@ -762,7 +758,6 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) && dsp->pcm_slot_rxpcm_slot_rx] = 0; } - dsp = dsp->next; } i = 0; ii = member->dsp->features.pcm_slots; @@ -787,7 +782,6 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) member->dsp->hfc_conf = current_conf; dsp_cmx_hw_message(member->dsp, HW_PCM_CONN, i, 2, i, 2); dsp_cmx_hw_message(member->dsp, HW_CONF_JOIN, current_conf, 0, 0, 0); - member = member->next; } return; } @@ -795,8 +789,7 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) /* no member is in a conference yet, so we find a free one */ memset(freeunits, 1, sizeof(freeunits)); - dsp = (dsp_t *)dsp_obj.ilist; - while(dsp) { + list_for_each_entry(dsp, &dsp_obj.ilist, list) { /* dsp must be on the same chip */ if (dsp->features.hfc_id==same_hfc /* dsp must have joined a HW conference */ @@ -804,7 +797,6 @@ dsp_cmx_hardware(conference_t *conf, dsp_t *dsp) /* slot must be within range */ && dsp->hfc_conf<8) freeunits[dsp->hfc_conf] = 0; - dsp = dsp->next; } i = 0; ii = 8; @@ -855,7 +847,7 @@ dsp_cmx_conf(dsp_t *dsp, u32 conf_id) dsp_cmx_hardware(NULL, dsp); /* conf now empty? */ - if (!conf->mlist) { + if (list_empty(&conf->mlist)) { if (dsp_debug & DEBUG_DSP_CMX) printk(KERN_DEBUG "conference is empty, so we remove it.\n"); err = dsp_cmx_del_conf(conf); @@ -891,7 +883,7 @@ dsp_cmx_conf(dsp_t *dsp, u32 conf_id) dsp->conf_id = conf_id; /* if we are alone, we do nothing! */ - if (!conf->mlist) { + if (list_empty(&conf->mlist)) { if (dsp_debug & DEBUG_DSP_CMX) printk(KERN_DEBUG "we are alone in this conference, so exit.\n"); /* update hardware */ @@ -954,8 +946,7 @@ dsp_cmx_receive(dsp_t *dsp, struct sk_buff *skb) else if (conf->largest > dsp->largest) dsp->largest = conf->largest; - member = conf->mlist; - while(member) { + list_for_each_entry(member, &conf->mlist, list) { if (member != dsp->member) { /* if W_rx is lower */ if (((member->dsp->W_rx - W_min) & CMX_BUFF_MASK) >= CMX_BUFF_HALF) @@ -964,7 +955,6 @@ dsp_cmx_receive(dsp_t *dsp, struct sk_buff *skb) if (((W_max - member->dsp->W_rx) & CMX_BUFF_MASK) >= CMX_BUFF_HALF) W_max = member->dsp->W_rx; } - member = member->next; } } @@ -990,9 +980,9 @@ dsp_cmx_receive(dsp_t *dsp, struct sk_buff *skb) if (conf) { #ifdef CMX_CONF_DEBUG #warning CMX_CONF_DEBUG is enabled, it causes performance loss with normal 2-party crossconnects - if (conf->mlist) if (conf->mlist->next) { + if (2 <= count_list_member(&conf->mlist)) { #else - if (conf->mlist) if (conf->mlist->next) if (conf->mlist->next->next) { + if (3 <= count_list_member(&conf->mlist)) { #endif //printk(KERN_DEBUG "cmxing dsp:%s dsp->W_rx=%04x conf->W_max=%04x\n", dsp->inst.name, dsp->W_rx, conf->W_max); /* -> received data is added to conf-buffer @@ -1158,19 +1148,19 @@ struct sk_buff dsp->R_tx = t; return(nskb); } - if (!conf->mlist->next) { + if (1 == count_list_member(&conf->mlist)) { goto single; } /* STEP 2.2: PROCESS DATA (two members) */ #ifdef CMX_CONF_DEBUG if (0) { #else - if (!conf->mlist->next->next) { + if (2 == count_list_member(&conf->mlist)) { #endif /* "other" becomes other party */ - other = conf->mlist->dsp; + other = (list_entry(conf->mlist.next, conf_member_t, list))->dsp; if (other == member) - other = conf->mlist->next->dsp; + other = (list_entry(conf->mlist.prev, conf_member_t, list))->dsp; o = other->rx_buff; /* received data */ /* -> if echo is NOT enabled */ if (!dsp->echo) { diff --git a/drivers/isdn/hardware/mISDN/dsp_core.c b/drivers/isdn/hardware/mISDN/dsp_core.c index 61b305c..7cf7831 100644 --- a/drivers/isdn/hardware/mISDN/dsp_core.c +++ b/drivers/isdn/hardware/mISDN/dsp_core.c @@ -677,7 +677,7 @@ release_dsp(dsp_t *dsp) conf = dsp->conf; if (conf) { dsp_cmx_del_conf_member(dsp); - if (!conf->mlist) { + if (!list_empty(&conf->mlist)) { dsp_cmx_del_conf(conf); } } @@ -695,7 +695,7 @@ release_dsp(dsp_t *dsp) if (dsp_debug & DEBUG_DSP_MGR) printk(KERN_DEBUG "%s: remove & destroy object %s\n", __FUNCTION__, dsp->inst.name); - REMOVE_FROM_LISTBASE(dsp, ((dsp_t *)dsp_obj.ilist)); + list_del(&dsp->list); dsp_obj.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL); unlock_HW(&dsp_lock); vfree(dsp); @@ -757,11 +757,11 @@ new_dsp(mISDNstack_t *st, mISDN_pid_t *pid) INIT_WORK(&ndsp->sendwork, (void *)(void *)sendevent, ndsp); lock_HW(&dsp_lock, 0); /* append and register */ - APPEND_TO_LIST(ndsp, ((dsp_t *)dsp_obj.ilist)); + list_add_tail(&ndsp->list, &dsp_obj.ilist); err = dsp_obj.ctrl(st, MGR_REGLAYER | INDICATION, &ndsp->inst); if (err) { printk(KERN_ERR "%s: failed to register layer %s\n", __FUNCTION__, ndsp->inst.name); - REMOVE_FROM_LISTBASE(ndsp, ((dsp_t *)dsp_obj.ilist)); + list_del(&ndsp->list); unlock_HW(&dsp_lock); goto free_mem; } @@ -811,17 +811,22 @@ dsp_feat(dsp_t *dsp) static int dsp_manager(void *data, u_int prim, void *arg) { mISDNinstance_t *inst = data; - dsp_t *dspl = (dsp_t *)dsp_obj.ilist; - int ret = 0; + dsp_t *dspl; + int ret = -EINVAL; if (dsp_debug & DEBUG_DSP_MGR) printk(KERN_DEBUG "%s: data:%p prim:%x arg:%p\n", __FUNCTION__, data, prim, arg); if (!data) - return(-EINVAL); - while(dspl) { - if (&dspl->inst == inst) + return(ret); + list_for_each_entry(dspl, &dsp_obj.ilist, list) { + if (&dspl->inst == inst) { + ret = 0; break; - dspl = dspl->next; + } + } + if (ret && (prim != (MGR_NEWLAYER | REQUEST))) { + printk(KERN_WARNING "%s: given instance(%p) not in ilist.\n", __FUNCTION__, data); + return(ret); } switch(prim) { @@ -829,39 +834,19 @@ dsp_manager(void *data, u_int prim, void *arg) { ret = new_dsp(data, arg); break; case MGR_CONNECT | REQUEST: - if (!dspl) { - printk(KERN_WARNING "%s: given instance(%p) not in ilist.\n", __FUNCTION__, data); - ret = -EINVAL; - break; - } ret = mISDN_ConnectIF(inst, arg); dsp_feat(dspl); break; case MGR_SETIF | REQUEST: case MGR_SETIF | INDICATION: - if (!dspl) { - printk(KERN_WARNING "%s: given instance(%p) not in ilist.\n", __FUNCTION__, data); - ret = -EINVAL; - break; - } ret = mISDN_SetIF(inst, arg, prim, dsp_from_up, dsp_from_down, dspl); break; case MGR_DISCONNECT | REQUEST: case MGR_DISCONNECT | INDICATION: - if (!dspl) { - printk(KERN_WARNING "%s: given instance(%p) not in ilist.\n", __FUNCTION__, data); - ret = -EINVAL; - break; - } ret = mISDN_DisConnectIF(inst, arg); break; case MGR_UNREGLAYER | REQUEST: case MGR_RELEASE | INDICATION: - if (!dspl) { - printk(KERN_WARNING "%s: given instance(%p) not in ilist.\n", __FUNCTION__, data); - ret = -EINVAL; - break; - } if (dsp_debug & DEBUG_DSP_MGR) printk(KERN_DEBUG "%s: release_dsp id %x\n", __FUNCTION__, dspl->inst.st->id); @@ -922,9 +907,7 @@ static int dsp_init(void) dsp_obj.name = DSPName; dsp_obj.BPROTO.protocol[3] = ISDN_PID_L3_B_DSP; dsp_obj.own_ctrl = dsp_manager; - dsp_obj.prev = NULL; - dsp_obj.next = NULL; - dsp_obj.ilist = NULL; + INIT_LIST_HEAD(&dsp_obj.ilist); /* initialize audio tables */ silence = (dsp_options&DSP_OPT_ULAW)?0xff:0x2a; @@ -954,7 +937,8 @@ static int dsp_init(void) */ static void dsp_cleanup(void) { - int err; + dsp_t *dspl, *nd; + int err; if (dsp_debug & DEBUG_DSP_MGR) printk(KERN_DEBUG "%s: removing module\n", __FUNCTION__); @@ -963,12 +947,12 @@ static void dsp_cleanup(void) printk(KERN_ERR "mISDN_dsp: Can't unregister Audio DSP error(%d)\n", err); } - if(dsp_obj.ilist) { + if (!list_empty(&dsp_obj.ilist)) { printk(KERN_WARNING "mISDN_dsp: Audio DSP object inst list not empty.\n"); - while(dsp_obj.ilist) - release_dsp(dsp_obj.ilist); + list_for_each_entry_safe(dspl, nd, &dsp_obj.ilist, list) + release_dsp(dspl); } - if (Conf_list) { + if (!list_empty(&Conf_list)) { printk(KERN_ERR "mISDN_dsp: Conference list not empty. Not all memory freed.\n"); } } diff --git a/drivers/isdn/hardware/mISDN/dtmf.c b/drivers/isdn/hardware/mISDN/dtmf.c index f8c3ca3..e20d85e 100644 --- a/drivers/isdn/hardware/mISDN/dtmf.c +++ b/drivers/isdn/hardware/mISDN/dtmf.c @@ -24,14 +24,13 @@ #define DTMF_NPOINTS 205 /* Number of samples for DTMF recognition */ typedef struct _dtmf { - struct _dtmf *prev; - struct _dtmf *next; - u_long Flags; - int debug; - char last; - int idx; - int buf[DTMF_NPOINTS]; - mISDNinstance_t inst; + struct list_head list; + u_long Flags; + int debug; + char last; + int idx; + int buf[DTMF_NPOINTS]; + mISDNinstance_t inst; } dtmf_t; #define FLG_DTMF_ULAW 1 @@ -490,7 +489,7 @@ release_dtmf(dtmf_t *dtmf) { inst->down.peer->obj->ctrl(inst->down.peer, MGR_DISCONNECT | REQUEST, &inst->down); } - REMOVE_FROM_LISTBASE(dtmf, ((dtmf_t *)dtmf_obj.ilist)); + list_del(&dtmf->list); dtmf_obj.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL); kfree(dtmf); } @@ -515,10 +514,10 @@ new_dtmf(mISDNstack_t *st, mISDN_pid_t *pid) { return(-ENOPROTOOPT); } n_dtmf->debug = debug; - APPEND_TO_LIST(n_dtmf, ((dtmf_t *)dtmf_obj.ilist)); + list_add_tail(&n_dtmf->list, &dtmf_obj.ilist); err = dtmf_obj.ctrl(st, MGR_REGLAYER | INDICATION, &n_dtmf->inst); if (err) { - REMOVE_FROM_LISTBASE(n_dtmf, ((dtmf_t *)dtmf_obj.ilist)); + list_del(&n_dtmf->list); kfree(n_dtmf); } return(err); @@ -559,23 +558,25 @@ MODULE_LICENSE("GPL"); static int dtmf_manager(void *data, u_int prim, void *arg) { - mISDNinstance_t *inst = data; - dtmf_t *dtmf_l = dtmf_obj.ilist; + mISDNinstance_t *inst = data; + dtmf_t *dtmf_l; + int ret = -EINVAL; if (debug & DEBUG_DTMF_MGR) printk(KERN_DEBUG "dtmf_manager data:%p prim:%x arg:%p\n", data, prim, arg); if (!data) - return(-EINVAL); - while(dtmf_l) { - if (&dtmf_l->inst == inst) + return(ret); + list_for_each_entry(dtmf_l, &dtmf_obj.ilist, list) { + if (&dtmf_l->inst == inst) { + ret = 0; break; - dtmf_l = dtmf_l->next; + } } if (prim == (MGR_NEWLAYER | REQUEST)) return(new_dtmf(data, arg)); - if (!dtmf_l) { + if (ret) { printk(KERN_WARNING "dtmf_manager prim(%x) no instance\n", prim); - return(-EINVAL); + return(ret); } switch(prim) { case MGR_CLRSTPARA | INDICATION: @@ -616,9 +617,7 @@ static int dtmf_init(void) dtmf_obj.name = MName; dtmf_obj.BPROTO.protocol[2] = ISDN_PID_L2_B_TRANSDTMF; dtmf_obj.own_ctrl = dtmf_manager; - dtmf_obj.prev = NULL; - dtmf_obj.next = NULL; - dtmf_obj.ilist = NULL; + INIT_LIST_HEAD(&dtmf_obj.ilist); if ((err = mISDN_register(&dtmf_obj))) { printk(KERN_ERR "Can't register %s error(%d)\n", MName, err); } @@ -627,15 +626,16 @@ static int dtmf_init(void) static void dtmf_cleanup(void) { - int err; + int err; + dtmf_t *dtmf, *nd; if ((err = mISDN_unregister(&dtmf_obj))) { printk(KERN_ERR "Can't unregister DTMF error(%d)\n", err); } - if(dtmf_obj.ilist) { + if (!list_empty(&dtmf_obj.ilist)) { printk(KERN_WARNING "dtmf inst list not empty\n"); - while(dtmf_obj.ilist) - release_dtmf(dtmf_obj.ilist); + list_for_each_entry_safe(dtmf, nd, &dtmf_obj.ilist, list) + release_dtmf(dtmf); } } diff --git a/drivers/isdn/hardware/mISDN/faxl3.c b/drivers/isdn/hardware/mISDN/faxl3.c index 640cf77..4bf2972 100644 --- a/drivers/isdn/hardware/mISDN/faxl3.c +++ b/drivers/isdn/hardware/mISDN/faxl3.c @@ -21,8 +21,7 @@ static int ttt=180; typedef struct _faxl3 { - struct _faxl3 *prev; - struct _faxl3 *next; + struct list_head list; spinlock_t lock; u_long state; int debug; @@ -1953,7 +1952,7 @@ release_faxl3(faxl3_t *faxl3) { inst->down.peer->obj->ctrl(inst->down.peer, MGR_DISCONNECT | REQUEST, &inst->down); } - REMOVE_FROM_LISTBASE(faxl3, ((faxl3_t *)faxl3_obj.ilist)); + list_del(&faxl3->list); discard_queue(&faxl3->downq); discard_queue(&faxl3->dataq); discard_queue(&faxl3->pageq); @@ -2048,7 +2047,7 @@ new_faxl3(mISDNstack_t *st, mISDN_pid_t *pid) { skb_queue_head_init(&n_faxl3->pageq); skb_queue_head_init(&n_faxl3->saveq); - APPEND_TO_LIST(n_faxl3, ((faxl3_t *)faxl3_obj.ilist)); + list_add_tail(&n_faxl3->list, &faxl3_obj.ilist); n_faxl3->entity = MISDN_ENTITY_NONE; err = faxl3_obj.ctrl(&n_faxl3->inst, MGR_NEWENTITY | REQUEST, NULL); if (err) { @@ -2057,7 +2056,7 @@ new_faxl3(mISDNstack_t *st, mISDN_pid_t *pid) { } err = faxl3_obj.ctrl(st, MGR_REGLAYER | INDICATION, &n_faxl3->inst); if (err) { - REMOVE_FROM_LISTBASE(n_faxl3, ((faxl3_t *)faxl3_obj.ilist)); + list_del(&n_faxl3->list); kfree(n_faxl3); } else { if (st->para.maxdatalen) @@ -2075,23 +2074,25 @@ new_faxl3(mISDNstack_t *st, mISDN_pid_t *pid) { static int faxl3_manager(void *data, u_int prim, void *arg) { - mISDNinstance_t *inst = data; - faxl3_t *faxl3_l = faxl3_obj.ilist; + mISDNinstance_t *inst = data; + faxl3_t *faxl3_l; + int err = -EINVAL; if (debug & DEBUG_FAXL3_MGR) printk(KERN_DEBUG "faxl3_manager data:%p prim:%x arg:%p\n", data, prim, arg); if (!data) - return(-EINVAL); - while(faxl3_l) { - if (&faxl3_l->inst == inst) + return(err); + list_for_each_entry(faxl3_l, &faxl3_obj.ilist, list) { + if (&faxl3_l->inst == inst) { + err = 0; break; - faxl3_l = faxl3_l->next; + } } if (prim == (MGR_NEWLAYER | REQUEST)) return(new_faxl3(data, arg)); - if (!faxl3_l) { + if (err) { printk(KERN_WARNING "faxl3_manager prim(%x) no instance\n", prim); - return(-EINVAL); + return(err); } switch(prim) { case MGR_CLRSTPARA | INDICATION: @@ -2145,9 +2146,7 @@ static int faxl3_init(void) faxl3_obj.name = MName; faxl3_obj.BPROTO.protocol[3] = ISDN_PID_L3_B_T30; faxl3_obj.own_ctrl = faxl3_manager; - faxl3_obj.prev = NULL; - faxl3_obj.next = NULL; - faxl3_obj.ilist = NULL; + INIT_LIST_HEAD(&faxl3_obj.ilist); if ((err = mISDN_register(&faxl3_obj))) { printk(KERN_ERR "Can't register %s error(%d)\n", MName, err); return(err); @@ -2167,15 +2166,16 @@ static int faxl3_init(void) static void faxl3_cleanup(void) { - int err; + faxl3_t *l3, *nl3; + int err; if ((err = mISDN_unregister(&faxl3_obj))) { printk(KERN_ERR "Can't unregister DTMF error(%d)\n", err); } - if(faxl3_obj.ilist) { + if(!list_empty(&faxl3_obj.ilist)) { printk(KERN_WARNING "faxl3 inst list not empty\n"); - while(faxl3_obj.ilist) - release_faxl3(faxl3_obj.ilist); + list_for_each_entry_safe(l3, nl3, &faxl3_obj.ilist, list) + release_faxl3(l3); } mISDN_FsmFree(&faxl3fsm); mISDN_FsmFree(&modfsm); diff --git a/drivers/isdn/hardware/mISDN/helper.c b/drivers/isdn/hardware/mISDN/helper.c index 3bf60fa..daf8470 100644 --- a/drivers/isdn/hardware/mISDN/helper.c +++ b/drivers/isdn/hardware/mISDN/helper.c @@ -321,9 +321,10 @@ mISDN_ConnectIF(mISDNinstance_t *owner, mISDNinstance_t *peer) int mISDN_DisConnectIF(mISDNinstance_t *inst, mISDNif_t *hif) { if (hif) { - if (hif->next && hif->next->owner) { - hif->next->owner->obj->ctrl(hif->next->owner, - MGR_DISCONNECT | REQUEST, hif->next); + if (hif->clone) { + if (hif->clone->owner) + hif->clone->owner->obj->ctrl(hif->clone->owner, + MGR_DISCONNECT | REQUEST, hif->clone); } if (inst->up.peer) { if (inst->up.peer == hif->owner) @@ -354,6 +355,10 @@ mISDN_init_instance(mISDNinstance_t *inst, mISDNobject_t *obj, void *data) 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); } diff --git a/drivers/isdn/hardware/mISDN/helper.h b/drivers/isdn/hardware/mISDN/helper.h index f5f842e..d66f2cc 100644 --- a/drivers/isdn/hardware/mISDN/helper.h +++ b/drivers/isdn/hardware/mISDN/helper.h @@ -20,42 +20,6 @@ printk(KERN_ERR "mISDN: INTERNAL ERROR in %s:%d " fmt "\n", \ __FILE__, __LINE__, ## arg) -#define APPEND_TO_LIST(item,base) \ - if (item->prev || item->next) \ - int_errtxt("APPEND not clean %p<-%p->%p", \ - item->prev, item, item->next); \ - item->next = NULL; \ - item->prev = base; \ - while (item->prev && item->prev->next) \ - item->prev = item->prev->next; \ - if (item->prev == item) { \ - int_errtxt("APPEND DUP %p", item); \ - } else \ - if (base) { \ - item->prev->next = item; \ - } else \ - base = item - -#define INSERT_INTO_LIST(newi,nexti,base) \ - newi->next = nexti; \ - newi->prev = nexti->prev; \ - if (newi->prev) \ - newi->prev->next = newi; \ - nexti->prev = newi; \ - if (base == nexti) \ - base = newi - -#define REMOVE_FROM_LIST(item) \ - if (item->prev) \ - item->prev->next = item->next; \ - if (item->next) \ - item->next->prev = item->prev - -#define REMOVE_FROM_LISTBASE(item,base) \ - REMOVE_FROM_LIST(item); \ - if (item == base) \ - base = item->next - static inline int discard_queue(struct sk_buff_head *q) { @@ -103,6 +67,17 @@ extern int mISDN_SetHandledPID(mISDNobject_t *, mISDN_pid_t *); extern void mISDN_RemoveUsedPID(mISDN_pid_t *, mISDN_pid_t *); extern void mISDN_init_instance(mISDNinstance_t *, mISDNobject_t *, void *); +static inline int +count_list_member(struct list_head *head) +{ + int cnt = 0; + struct list_head *m; + + list_for_each(m, head) + cnt++; + return(cnt); +} + static inline int mISDN_HasProtocolP(mISDNobject_t *obj, int *PP) { diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.c b/drivers/isdn/hardware/mISDN/hfc_multi.c index 05f1ef3..e8f810b 100644 --- a/drivers/isdn/hardware/mISDN/hfc_multi.c +++ b/drivers/isdn/hardware/mISDN/hfc_multi.c @@ -2191,7 +2191,7 @@ hfcmulti_dch_bh(dchannel_t *dch) if (hc->created[hc->chan[ch].port]) { while(upif) { if_link(upif, prim, para, 0, NULL, 0); - upif = upif->next; + upif = upif->clone; } } } @@ -2479,11 +2479,12 @@ init_card(hfc_multi_t *hc) static int SelFreeBChannel(hfc_multi_t *hc, int ch, channel_info_t *ci) { - bchannel_t *bch; - hfc_multi_t *hfc; - mISDNstack_t *bst; - int cnr; - int port = hc->chan[ch].port; + bchannel_t *bch; + hfc_multi_t *hfc; + mISDNstack_t *bst; + struct list_head *head; + int cnr; + int port = hc->chan[ch].port; if (port < 0 || port>=hc->type) { printk(KERN_WARNING "%s: port(%d) out of range", __FUNCTION__, port); @@ -2493,9 +2494,20 @@ SelFreeBChannel(hfc_multi_t *hc, int ch, channel_info_t *ci) if (!ci) return(-EINVAL); ci->st.p = NULL; - bst = hc->chan[ch].dch->inst.st->child; cnr=0; - while(bst) { + bst = hc->chan[ch].dch->inst.st; + if (list_empty(&bst->childlist)) { + if ((bst->id & FLG_CLONE_STACK) && + (bst->childlist.prev != &bst->childlist)) { + head = bst->childlist.prev; + } else { + printk(KERN_ERR "%s: invalid empty childlist (no clone) stid(%x) childlist(%p<-%p->%p)\n", + __FUNCTION__, bst->id, bst->childlist.prev, &bst->childlist, bst->childlist.next); + return(-EINVAL); + } + } else + head = &bst->childlist; + list_for_each_entry(bst, head, list) { if (cnr == ((hc->type==1)?30:2)) /* 30 or 2 B-channels */ { printk(KERN_WARNING "%s: fatal error: more b-stacks than ports", __FUNCTION__); return(-EINVAL); @@ -2529,7 +2541,6 @@ SelFreeBChannel(hfc_multi_t *hc, int ch, channel_info_t *ci) } } cnr++; - bst = bst->next; } return(-EBUSY); } @@ -2783,7 +2794,7 @@ release_port(hfc_multi_t *hc, int port) if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: removing object from listbase\n", __FUNCTION__); - REMOVE_FROM_LISTBASE(hc, ((hfc_multi_t *)HFCM_obj.ilist)); + list_del(&hc->list); kfree(hc); } @@ -2793,7 +2804,7 @@ release_port(hfc_multi_t *hc, int port) static int HFC_manager(void *data, u_int prim, void *arg) { - hfc_multi_t *hc = HFCM_obj.ilist; + hfc_multi_t *hc; mISDNinstance_t *inst = data; struct sk_buff *skb; dchannel_t *dch = NULL; @@ -2808,7 +2819,7 @@ HFC_manager(void *data, u_int prim, void *arg) } /* find channel and card */ - while(hc) { + list_for_each_entry(hc, &HFCM_obj.ilist, list) { i = 0; while(i < 32) { //printk(KERN_DEBUG "comparing (D-channel) card=%08x inst=%08x with inst=%08x\n", hc, &hc->dch[i].inst, inst); @@ -2828,8 +2839,6 @@ HFC_manager(void *data, u_int prim, void *arg) } if (ch >= 0) break; - - hc = hc->next; } if (ch < 0) { printk(KERN_ERR "%s: no card/channel found data %p prim %x arg %p\n", __FUNCTION__, data, prim, arg); @@ -2955,7 +2964,7 @@ static int __init HFCmulti_init(void) { int err, err2, i; - hfc_multi_t *hc; + hfc_multi_t *hc,*next; mISDN_pid_t pid, pids[MAX_CARDS]; mISDNstack_t *dst = NULL; /* make gcc happy */ int port_cnt; @@ -3004,6 +3013,7 @@ HFCmulti_init(void) #ifdef MODULE HFCM_obj.owner = THIS_MODULE; #endif + INIT_LIST_HEAD(&HFCM_obj.ilist); HFCM_obj.name = HFCName; HFCM_obj.own_ctrl = HFC_manager; HFCM_obj.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0 | ISDN_PID_L0_NT_S0 @@ -3087,7 +3097,7 @@ HFCmulti_init(void) if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: (after APPEND_TO_LIST)\n", __FUNCTION__); - APPEND_TO_LIST(hc, ((hfc_multi_t *)HFCM_obj.ilist)); + list_add_tail(&hc->list, &HFCM_obj.ilist); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: (after APPEND_TO_LIST)\n", __FUNCTION__); @@ -3415,7 +3425,7 @@ HFCmulti_init(void) } if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: before REMOVE_FROM_LIST (refcnt = %d)\n", __FUNCTION__, HFCM_obj.refcnt); - REMOVE_FROM_LISTBASE(hc, ((hfc_multi_t *)HFCM_obj.ilist)); + list_del(&hc->list); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: after REMOVE_FROM_LIST (refcnt = %d)\n", __FUNCTION__, HFCM_obj.refcnt); kfree(hc); @@ -3426,9 +3436,9 @@ HFCmulti_init(void) if ((err2 = mISDN_unregister(&HFCM_obj))) { printk(KERN_ERR "Can't unregister HFC-Multi cards error(%d)\n", err); } - while(HFCM_obj.ilist) { + list_for_each_entry_safe(hc, next, &HFCM_obj.ilist, list) { printk(KERN_ERR "HFC PCI card struct not empty refs %d\n", HFCM_obj.refcnt); - release_port(HFCM_obj.ilist, -1); /* all ports */ + release_port(hc, -1); /* all ports */ } if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: after mISDN_unregister (refcnt = %d)\n", __FUNCTION__, HFCM_obj.refcnt); @@ -3443,6 +3453,7 @@ HFCmulti_init(void) static void __exit HFCmulti_cleanup(void) { + hfc_multi_t *hc,*next; int err; if (debug & DEBUG_HFCMULTI_INIT) @@ -3452,9 +3463,10 @@ HFCmulti_cleanup(void) } if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: now checking ilist (refcnt = %d)\n", __FUNCTION__, HFCM_obj.refcnt); - while(HFCM_obj.ilist) { + + list_for_each_entry_safe(hc, next, &HFCM_obj.ilist, list) { printk(KERN_ERR "HFC PCI card struct not empty refs %d\n", HFCM_obj.refcnt); - release_port(HFCM_obj.ilist, -1); /* all ports */ + release_port(hc, -1); /* all ports */ } if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: done (refcnt = %d)\n", __FUNCTION__, HFCM_obj.refcnt); diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h index f89eab3..ca4265f 100644 --- a/drivers/isdn/hardware/mISDN/hfc_multi.h +++ b/drivers/isdn/hardware/mISDN/hfc_multi.h @@ -86,9 +86,7 @@ typedef struct hfcmulti_hw hfcmulti_hw_t; #define HFC_CHIP_CLOCK2 6 /* double clock mode */ struct hfc_multi { - struct hfc_multi *prev; - struct hfc_multi *next; - + struct list_head list; char name[32]; int id; /* chip number starting with 1 */ int pcm; /* id of pcm bus */ diff --git a/drivers/isdn/hardware/mISDN/hfc_pci.c b/drivers/isdn/hardware/mISDN/hfc_pci.c index dc4642c..2fa3ab0 100644 --- a/drivers/isdn/hardware/mISDN/hfc_pci.c +++ b/drivers/isdn/hardware/mISDN/hfc_pci.c @@ -158,17 +158,16 @@ typedef struct hfcPCI_hw hfcPCI_hw_t; #define HFC_CFG_SW_DD_DU 7 typedef struct _hfc_pci { - struct _hfc_pci *prev; - struct _hfc_pci *next; - u_char subtyp; - u_char chanlimit; - u_long cfg; - u_int irq; - u_int irqcnt; - hfcPCI_hw_t hw; - mISDN_HWlock_t lock; - dchannel_t dch; - bchannel_t bch[2]; + struct list_head list; + u_char subtyp; + u_char chanlimit; + u_long cfg; + u_int irq; + u_int irqcnt; + hfcPCI_hw_t hw; + mISDN_HWlock_t lock; + dchannel_t dch; + bchannel_t bch[2]; } hfc_pci_t; @@ -1915,7 +1914,7 @@ HW_hfcD_bh(dchannel_t *dch) } while(upif) { if_link(upif, prim, para, 0, NULL, 0); - upif = upif->next; + upif = upif->clone; } } } @@ -2034,17 +2033,29 @@ static int init_card(hfc_pci_t *hc) static int SelFreeBChannel(hfc_pci_t *hc, channel_info_t *ci) { - bchannel_t *bch; - hfc_pci_t *hfc; - mISDNstack_t *bst; - u_int cnr; + bchannel_t *bch; + hfc_pci_t *hfc; + mISDNstack_t *bst; + u_int cnr; + struct list_head *head; if (!ci) return(-EINVAL); ci->st.p = NULL; - bst = hc->dch.inst.st->child; cnr=0; - while(bst) { + bst = hc->dch.inst.st; + if (list_empty(&bst->childlist)) { + if ((bst->id & FLG_CLONE_STACK) && + (bst->childlist.prev != &bst->childlist)) { + head = bst->childlist.prev; + } else { + printk(KERN_ERR "%s: invalid empty childlist (no clone) stid(%x) childlist(%p<-%p->%p)\n", + __FUNCTION__, bst->id, bst->childlist.prev, &bst->childlist, bst->childlist.next); + return(-EINVAL); + } + } else + head = &bst->childlist; + list_for_each_entry(bst, head, list) { if(!bst->mgr) { int_errtxt("no mgr st(%p)", bst); return(-EINVAL); @@ -2076,7 +2087,6 @@ SelFreeBChannel(hfc_pci_t *hc, channel_info_t *ci) } } cnr++; - bst = bst->next; } return(-EBUSY); } @@ -2178,12 +2188,12 @@ setup_hfcpci(hfc_pci_t *hc) /* Allocate memory for FIFOS */ /* Because the HFC-PCI needs a 32K physical alignment, we */ /* need to allocate the double mem and align the address */ - if (!((void *) hc->hw.share_start = kmalloc(65536, GFP_KERNEL))) { + if (!(hc->hw.share_start = kmalloc(65536, GFP_KERNEL))) { printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n"); return 1; } - (ulong) hc->hw.fifos = - (((ulong) hc->hw.share_start) & ~0x7FFF) + 0x8000; + hc->hw.fifos = (void *) + ((((ulong) hc->hw.share_start) & ~0x7FFF) + 0x8000); pci_write_config_dword(hc->hw.dev, 0x80, (u_int) virt_to_bus(hc->hw.fifos)); hc->hw.pci_io = ioremap((ulong) hc->hw.pci_io, 256); printk(KERN_INFO @@ -2234,14 +2244,14 @@ release_card(hfc_pci_t *hc) { 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, MGR_UNREGLAYER | REQUEST, NULL); - REMOVE_FROM_LISTBASE(hc, ((hfc_pci_t *)HFC_obj.ilist)); + list_del(&hc->list); unlock_dev(hc); kfree(hc); } static int HFC_manager(void *data, u_int prim, void *arg) { - hfc_pci_t *card = HFC_obj.ilist; + hfc_pci_t *card; mISDNinstance_t *inst = data; struct sk_buff *skb; int channel = -1; @@ -2252,7 +2262,7 @@ HFC_manager(void *data, u_int prim, void *arg) { __FUNCTION__, prim, arg); return(-EINVAL); } - while(card) { + list_for_each_entry(card, &HFC_obj.ilist, list) { if (&card->dch.inst == inst) { channel = 2; break; @@ -2266,7 +2276,6 @@ HFC_manager(void *data, u_int prim, void *arg) { channel = 1; break; } - card = card->next; } if (channel<0) { printk(KERN_ERR "%s: no channel data %p prim %x arg %p\n", @@ -2371,6 +2380,7 @@ static int __init HFC_init(void) #ifdef MODULE HFC_obj.owner = THIS_MODULE; #endif + INIT_LIST_HEAD(&HFC_obj.ilist); HFC_obj.name = HFCName; HFC_obj.own_ctrl = HFC_manager; HFC_obj.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0 | @@ -2380,8 +2390,6 @@ static int __init HFC_init(void) ISDN_PID_L1_B_64HDLC; HFC_obj.BPROTO.protocol[2] = ISDN_PID_L2_B_TRANS | ISDN_PID_L2_B_RAWDEV; - HFC_obj.prev = NULL; - HFC_obj.next = NULL; if ((err = mISDN_register(&HFC_obj))) { printk(KERN_ERR "Can't register HFC PCI error(%d)\n", err); return(err); @@ -2393,7 +2401,7 @@ static int __init HFC_init(void) return(-ENOMEM); } memset(card, 0, sizeof(hfc_pci_t)); - APPEND_TO_LIST(card, ((hfc_pci_t *)HFC_obj.ilist)); + list_add_tail(&card->list, &HFC_obj.ilist); card->dch.debug = debug; lock_HW_init(&card->lock); card->dch.inst.lock = lock_dev; @@ -2420,7 +2428,10 @@ static int __init HFC_init(void) } } if (protocol[HFC_cnt] == 0x100) { - prev = card->prev; + if (card->list.prev == &HFC_obj.ilist) + prev = NULL; + else + prev = list_entry(card->list.prev, hfc_pci_t, list); if (!prev) { int_errtxt("card(%d) no previous HFC", @@ -2475,7 +2486,7 @@ static int __init HFC_init(void) mISDN_free_dch(&card->dch); mISDN_free_bch(&card->bch[1]); mISDN_free_bch(&card->bch[0]); - REMOVE_FROM_LISTBASE(card, ((hfc_pci_t *)HFC_obj.ilist)); + list_del(&card->list); kfree(card); if (!HFC_cnt) { mISDN_unregister(&HFC_obj); @@ -2545,14 +2556,16 @@ static int __init HFC_init(void) #ifdef MODULE static void __exit HFC_cleanup(void) { - int err; + hfc_pci_t *card, *next; + int err; + if ((err = mISDN_unregister(&HFC_obj))) { printk(KERN_ERR "Can't unregister HFC PCI error(%d)\n", err); } - while(HFC_obj.ilist) { + list_for_each_entry_safe(card, next, &HFC_obj.ilist, list) { printk(KERN_ERR "HFC PCI card struct not empty refs %d\n", HFC_obj.refcnt); - release_card(HFC_obj.ilist); + release_card(card); } return; } diff --git a/drivers/isdn/hardware/mISDN/isac.c b/drivers/isdn/hardware/mISDN/isac.c index f3297f4..d0424ae 100644 --- a/drivers/isdn/hardware/mISDN/isac.c +++ b/drivers/isdn/hardware/mISDN/isac.c @@ -92,7 +92,7 @@ isac_new_ph(dchannel_t *dch) } while(upif) { if_link(upif, prim, para, 0, NULL, 0); - upif = upif->next; + upif = upif->clone; } } diff --git a/drivers/isdn/hardware/mISDN/l3_udss1.c b/drivers/isdn/hardware/mISDN/l3_udss1.c index 95138c6..3853504 100644 --- a/drivers/isdn/hardware/mISDN/l3_udss1.c +++ b/drivers/isdn/hardware/mISDN/l3_udss1.c @@ -1516,7 +1516,7 @@ l3dss1_global_restart(l3_process_t *pc, u_char pr, void *arg) u_char *p, ri, ch = 0, chan = 0; struct sk_buff *skb = arg; Q931_info_t *qi = (Q931_info_t *)skb->data; - l3_process_t *up; + l3_process_t *up, *n; // newl3state(pc, 2); L3DelTimer(&pc->timer); @@ -1539,13 +1539,11 @@ l3dss1_global_restart(l3_process_t *pc, u_char pr, void *arg) if (pc->l3->debug) l3_debug(pc->l3, "Restart for channel %d", chan); } - up = pc->l3->proc; - while (up) { + list_for_each_entry_safe(up, n, &pc->l3->plist, list) { if ((ri & 7) == 7) dss1man(up, CC_RESTART | REQUEST, NULL); else if (up->bc == chan) mISDN_l3up(up, CC_RESTART | REQUEST, NULL); - up = up->next; } dev_kfree_skb(skb); skb = MsgStart(pc, MT_RESTART_ACKNOWLEDGE, chan ? 6 : 3); @@ -2221,7 +2219,7 @@ release_udss1(layer3_t *l3) inst->down.peer->obj->ctrl(inst->down.peer, MGR_DISCONNECT | REQUEST, &inst->down); } - REMOVE_FROM_LISTBASE(l3, ((layer3_t *)u_dss1.ilist)); + list_del(&l3->list); u_dss1.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL); if (l3->entity != MISDN_ENTITY_NONE) u_dss1.ctrl(inst, MGR_DELENTITY | REQUEST, (void *)l3->entity); @@ -2270,7 +2268,7 @@ new_udss1(mISDNstack_t *st, mISDN_pid_t *pid) nl3->global->state = 0; nl3->global->callref = 0; nl3->global->id = MISDN_ID_GLOBAL; - nl3->global->next = NULL; + INIT_LIST_HEAD(&nl3->global->list); nl3->global->n303 = N303; nl3->global->l3 = nl3; nl3->global->t303skb = NULL; @@ -2284,14 +2282,14 @@ new_udss1(mISDNstack_t *st, mISDN_pid_t *pid) nl3->dummy->state = 0; nl3->dummy->callref = -1; nl3->dummy->id = MISDN_ID_DUMMY; - nl3->dummy->next = NULL; + INIT_LIST_HEAD(&nl3->dummy->list); nl3->dummy->n303 = N303; nl3->dummy->l3 = nl3; nl3->dummy->t303skb = NULL; L3InitTimer(nl3->dummy, &nl3->dummy->timer); sprintf(nl3->inst.name, "DSS1 %d", st->id); nl3->p_mgr = dss1man; - APPEND_TO_LIST(nl3, ((layer3_t *)u_dss1.ilist)); + list_add_tail(&nl3->list, &u_dss1.ilist); err = u_dss1.ctrl(&nl3->inst, MGR_NEWENTITY | REQUEST, NULL); if (err) { printk(KERN_WARNING "mISDN %s: MGR_NEWENTITY REQUEST failed err(%x)\n", @@ -2300,7 +2298,7 @@ new_udss1(mISDNstack_t *st, mISDN_pid_t *pid) err = u_dss1.ctrl(st, MGR_REGLAYER | INDICATION, &nl3->inst); if (err) { release_l3(nl3); - REMOVE_FROM_LISTBASE(nl3, ((layer3_t *)u_dss1.ilist)); + list_del(&nl3->list); kfree(nl3); } else { mISDN_stPara_t stp; @@ -2328,17 +2326,18 @@ MODULE_PARM(debug, "1i"); static int udss1_manager(void *data, u_int prim, void *arg) { mISDNinstance_t *inst = data; - layer3_t *l3l = u_dss1.ilist; + layer3_t *l3l; if (debug & 0x1000) printk(KERN_DEBUG "udss1_manager data:%p prim:%x arg:%p\n", data, prim, arg); if (!data) return(-EINVAL); - while(l3l) { + list_for_each_entry(l3l, &u_dss1.ilist, list) { if (&l3l->inst == inst) break; - l3l = l3l->next; } + if (&l3l->list == &u_dss1.ilist) + l3l = NULL; if (prim == (MGR_NEWLAYER | REQUEST)) return(new_udss1(data, arg)); if (!l3l) { @@ -2387,14 +2386,13 @@ int UDSS1Init(void) #ifdef MODULE u_dss1.owner = THIS_MODULE; #endif + INIT_LIST_HEAD(&u_dss1.ilist); u_dss1.name = MName; u_dss1.DPROTO.protocol[3] = ISDN_PID_L3_DSS1USER | ISDN_PID_L3_DF_PTP | ISDN_PID_L3_DF_EXTCID | ISDN_PID_L3_DF_CRLEN2; u_dss1.own_ctrl = udss1_manager; - u_dss1.prev = NULL; - u_dss1.next = NULL; mISDNl3New(); if ((err = mISDN_register(&u_dss1))) { printk(KERN_ERR "Can't register %s error(%d)\n", MName, err); @@ -2407,14 +2405,15 @@ int UDSS1Init(void) void UDSS1_cleanup(void) { int err; + layer3_t *l3, *next; if ((err = mISDN_unregister(&u_dss1))) { printk(KERN_ERR "Can't unregister User DSS1 error(%d)\n", err); } - if (u_dss1.ilist) { + if (!list_empty(&u_dss1.ilist)) { printk(KERN_WARNING "mISDNl3 u_dss1 list not empty\n"); - while(u_dss1.ilist) - release_udss1(u_dss1.ilist); + list_for_each_entry_safe(l3, next, &u_dss1.ilist, list) + release_udss1(l3); } mISDNl3Free(); } diff --git a/drivers/isdn/hardware/mISDN/layer1.c b/drivers/isdn/hardware/mISDN/layer1.c index ac7d571..6780032 100644 --- a/drivers/isdn/hardware/mISDN/layer1.c +++ b/drivers/isdn/hardware/mISDN/layer1.c @@ -19,14 +19,13 @@ static char *l1_revision = "$Revision$"; #include "debug.h" typedef struct _layer1 { - struct _layer1 *prev; - struct _layer1 *next; - u_long Flags; - struct FsmInst l1m; - struct FsmTimer timer; - int debug; - int delay; - mISDNinstance_t inst; + struct list_head list; + u_long Flags; + struct FsmInst l1m; + struct FsmTimer timer; + int debug; + int delay; + mISDNinstance_t inst; } layer1_t; /* l1 status_info */ @@ -614,7 +613,7 @@ release_l1(layer1_t *l1) { inst->down.peer->obj->ctrl(inst->down.peer, MGR_DISCONNECT | REQUEST, &inst->down); } - REMOVE_FROM_LISTBASE(l1, ((layer1_t *)isdnl1.ilist)); + list_del(&l1->list); isdnl1.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL); kfree(l1); } @@ -656,11 +655,11 @@ new_l1(mISDNstack_t *st, mISDN_pid_t *pid) { nl1->l1m.userint = 0; nl1->l1m.printdebug = l1m_debug; mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer); - APPEND_TO_LIST(nl1, ((layer1_t *)isdnl1.ilist)); + list_add_tail(&nl1->list, &isdnl1.ilist); err = isdnl1.ctrl(st, MGR_REGLAYER | INDICATION, &nl1->inst); if (err) { mISDN_FsmDelTimer(&nl1->timer, 0); - REMOVE_FROM_LISTBASE(nl1, ((layer1_t *)isdnl1.ilist)); + list_del(&nl1->list); kfree(nl1); } return(err); @@ -699,66 +698,57 @@ MODULE_LICENSE("GPL"); static int l1_manager(void *data, u_int prim, void *arg) { - mISDNinstance_t *inst = data; - layer1_t *l1l = isdnl1.ilist; + mISDNinstance_t *inst = data; + layer1_t *l1l; + int err = -EINVAL; if (debug & 0x10000) printk(KERN_DEBUG "%s: data(%p) prim(%x) arg(%p)\n", __FUNCTION__, data, prim, arg); if (!data) - return(-EINVAL); - while(l1l) { - if (&l1l->inst == inst) + return(err); + list_for_each_entry(l1l, &isdnl1.ilist, list) { + if (&l1l->inst == inst) { + err = 0; break; - l1l = l1l->next; + } } + if (err && (prim != (MGR_NEWLAYER | REQUEST))) { + printk(KERN_WARNING "l1_manager connect no instance\n"); + return(err); + } + switch(prim) { case MGR_NEWLAYER | REQUEST: - return(new_l1(data, arg)); + err = new_l1(data, arg); + break; case MGR_CONNECT | REQUEST: - if (!l1l) { - printk(KERN_WARNING "l1_manager connect no instance\n"); - return(-EINVAL); - } - return(mISDN_ConnectIF(inst, arg)); + err = mISDN_ConnectIF(inst, arg); break; case MGR_SETIF | REQUEST: case MGR_SETIF | INDICATION: - if (!l1l) { - printk(KERN_WARNING "l1_manager setif no instance\n"); - return(-EINVAL); - } - return(mISDN_SetIF(inst, arg, prim, l1from_up, l1from_down, l1l)); + err = mISDN_SetIF(inst, arg, prim, l1from_up, l1from_down, l1l); break; case MGR_DISCONNECT | REQUEST: case MGR_DISCONNECT | INDICATION: - if (!l1l) { - printk(KERN_WARNING "l1_manager disconnect no instance\n"); - return(-EINVAL); - } - return(mISDN_DisConnectIF(inst, arg)); + err = mISDN_DisConnectIF(inst, arg); break; case MGR_UNREGLAYER | REQUEST: case MGR_RELEASE | INDICATION: - if (l1l) { - printk(KERN_DEBUG "release_l1 id %x\n", l1l->inst.st->id); - release_l1(l1l); - } else - printk(KERN_WARNING "l1_manager release no instance\n"); - break; + printk(KERN_DEBUG "release_l1 id %x\n", l1l->inst.st->id); + release_l1(l1l); + break; case MGR_STATUS | REQUEST: - if (!l1l) { - printk(KERN_WARNING "l1_manager status l1 no instance\n"); - return(-EINVAL); - } - return(l1_status(l1l, arg)); + err = l1_status(l1l, arg); + break; PRIM_NOT_HANDLED(MGR_CTRLREADY|INDICATION); PRIM_NOT_HANDLED(MGR_ADDSTPARA|INDICATION); default: printk(KERN_WARNING "l1_manager prim %x not handled\n", prim); - return(-EINVAL); + err = -EINVAL; + break; } - return(0); + return(err); } int Isdnl1Init(void) @@ -772,9 +762,7 @@ int Isdnl1Init(void) isdnl1.name = MName; isdnl1.DPROTO.protocol[1] = ISDN_PID_L1_TE_S0; isdnl1.own_ctrl = l1_manager; - isdnl1.prev = NULL; - isdnl1.next = NULL; - isdnl1.ilist = NULL; + INIT_LIST_HEAD(&isdnl1.ilist); #ifdef mISDN_UINTERFACE isdnl1.DPROTO.protocol[1] |= ISDN_PID_L1_TE_U; l1fsm_u.state_count = L1U_STATE_COUNT; @@ -807,15 +795,16 @@ int Isdnl1Init(void) #ifdef MODULE void cleanup_module(void) { - int err; + int err; + layer1_t *l1, *nl1; if ((err = mISDN_unregister(&isdnl1))) { printk(KERN_ERR "Can't unregister ISDN layer 1 error(%d)\n", err); } - if(isdnl1.ilist) { + if(!list_empty(&isdnl1.ilist)) { printk(KERN_WARNING "mISDNl1 inst list not empty\n"); - while(isdnl1.ilist) - release_l1(isdnl1.ilist); + list_for_each_entry_safe(l1, nl1, &isdnl1.ilist, list) + release_l1(l1); } #ifdef mISDN_UINTERFACE mISDN_FsmFree(&l1fsm_u); diff --git a/drivers/isdn/hardware/mISDN/layer2.c b/drivers/isdn/hardware/mISDN/layer2.c index 0a2be9b..f5edc18 100644 --- a/drivers/isdn/hardware/mISDN/layer2.c +++ b/drivers/isdn/hardware/mISDN/layer2.c @@ -200,7 +200,7 @@ static int ph_data_confirm(mISDNif_t *up, mISDN_head_t *hh, struct sk_buff *skb) { layer2_t *l2 = up->fdata; struct sk_buff *nskb = skb; - mISDNif_t *next = up->next; + mISDNif_t *next = up->clone; int ret = -EAGAIN; if (test_bit(FLG_L1_BUSY, &l2->flag)) { @@ -1885,16 +1885,18 @@ l2from_down(mISDNif_t *hif, 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; hh = mISDN_HEAD_P(askb); + next = hif->clone; // printk(KERN_DEBUG "%s: prim(%x)\n", __FUNCTION__, hh->prim); if (!l2) { - if (hif->next && hif->next->func) - ret = hif->next->func(hif->next, askb); + if (next && next->func) + ret = next->func(next, askb); return(ret); } if (hh->prim == (PH_DATA | CONFIRM)) @@ -1912,14 +1914,14 @@ l2from_down(mISDNif_t *hif, struct sk_buff *askb) } } } - if (hif->next && hif->next->func) - ret = hif->next->func(hif->next, askb); + if (next && next->func) + ret = next->func(next, askb); return(ret); } - if (hif->next) { - if (hif->next->func) { + if (next) { + if (next->func) { if (!(cskb = skb_clone(askb, GFP_ATOMIC))) - return(hif->next->func(hif->next, askb)); + return(next->func(next, askb)); else sh = *hh; } @@ -1960,9 +1962,9 @@ l2from_down(mISDNif_t *hif, struct sk_buff *askb) dev_kfree_skb(cskb); ret = 0; } - if (hif->next && hif->next->func) { + if (next && next->func) { *hh = sh; - ret = hif->next->func(hif->next, askb); + ret = next->func(next, askb); } return(ret); } @@ -2096,14 +2098,17 @@ release_l2(layer2_t *l2) if (l2->cloneif) { printk(KERN_DEBUG "%s: cloneif(%p) owner(%p) peer(%p)\n", __FUNCTION__, l2->cloneif, l2->cloneif->owner, l2->cloneif->peer); - REMOVE_FROM_LIST(l2->cloneif); + if (l2->cloneif->predecessor) + l2->cloneif->predecessor->clone = l2->cloneif->clone; + if (l2->cloneif->clone) + l2->cloneif->clone->predecessor = l2->cloneif->predecessor; if (l2->cloneif->owner && - (l2->cloneif->owner->up.next == l2->cloneif)) - l2->cloneif->owner->up.next = l2->cloneif->next; + (l2->cloneif->owner->up.clone == l2->cloneif)) + l2->cloneif->owner->up.clone = l2->cloneif->clone; kfree(l2->cloneif); l2->cloneif = NULL; } - REMOVE_FROM_LISTBASE(l2, ((layer2_t *)isdnl2.ilist)); + list_del(&l2->list); isdnl2.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL); if (l2->entity != MISDN_ENTITY_NONE) isdnl2.ctrl(inst, MGR_DELENTITY | REQUEST, (void *)l2->entity); @@ -2225,7 +2230,7 @@ new_l2(mISDNstack_t *st, mISDN_pid_t *pid, layer2_t **newl2) { mISDN_FsmInitTimer(&nl2->l2m, &nl2->t200); mISDN_FsmInitTimer(&nl2->l2m, &nl2->t203); - APPEND_TO_LIST(nl2, ((layer2_t *)isdnl2.ilist)); + list_add_tail(&nl2->list, &isdnl2.ilist); err = isdnl2.ctrl(&nl2->inst, MGR_NEWENTITY | REQUEST, NULL); if (err) { printk(KERN_WARNING "mISDN %s: MGR_NEWENTITY REQUEST failed err(%x)\n", @@ -2235,7 +2240,7 @@ new_l2(mISDNstack_t *st, mISDN_pid_t *pid, layer2_t **newl2) { if (err) { mISDN_FsmDelTimer(&nl2->t200, 0); mISDN_FsmDelTimer(&nl2->t203, 0); - REMOVE_FROM_LISTBASE(nl2, ((layer2_t *)isdnl2.ilist)); + list_del(&nl2->list); kfree(nl2); nl2 = NULL; } else { @@ -2286,7 +2291,10 @@ clone_l2(layer2_t *l2, mISDNinstance_t **new_ip) { nif->owner = l2->inst.down.peer; nif->peer = &nl2->inst; nif->stat = IF_DOWN; - APPEND_TO_LIST(nif, nif->owner->up.next); + nif->predecessor = &nif->owner->up; + while(nif->predecessor->clone) + nif->predecessor = nif->predecessor->clone; + nif->predecessor->clone = nif; nl2->inst.down.owner = &nl2->inst; nl2->inst.down.peer = &l2->inst; nl2->inst.down.func = l2_chain_down; @@ -2347,25 +2355,27 @@ MODULE_PARM(debug, "1i"); static int l2_manager(void *data, u_int prim, void *arg) { - mISDNinstance_t *inst = data; - layer2_t *l2l = isdnl2.ilist;; + mISDNinstance_t *inst = data; + layer2_t *l2l; + int err = -EINVAL; if (debug & 0x1000) printk(KERN_DEBUG "%s: data:%p prim:%x arg:%p\n", __FUNCTION__, data, prim, arg); if (!data) - return(-EINVAL); - while(l2l) { - if (&l2l->inst == inst) + return(err); + list_for_each_entry(l2l, &isdnl2.ilist, list) { + if (&l2l->inst == inst) { + err = 0; break; - l2l = l2l->next; + } } if (prim == (MGR_NEWLAYER | REQUEST)) return(new_l2(data, arg, NULL)); - if (!l2l) { + if (err) { if (debug & 0x1) printk(KERN_WARNING "l2_manager prim(%x) l2 no instance\n", prim); - return(-EINVAL); + return(err); } switch(prim) { case MGR_NEWENTITY | CONFIRM: @@ -2423,8 +2433,7 @@ int Isdnl2_Init(void) ISDN_PID_L2_DF_PTP; isdnl2.BPROTO.protocol[2] = ISDN_PID_L2_B_X75SLP; isdnl2.own_ctrl = l2_manager; - isdnl2.prev = NULL; - isdnl2.next = NULL; + INIT_LIST_HEAD(&isdnl2.ilist); l2fsm.state_count = L2_STATE_COUNT; l2fsm.event_count = L2_EVENT_COUNT; l2fsm.strEvent = strL2Event; @@ -2440,15 +2449,16 @@ int Isdnl2_Init(void) void Isdnl2_cleanup(void) { - int err; + int err; + layer2_t *l2, *nl2; if ((err = mISDN_unregister(&isdnl2))) { printk(KERN_ERR "Can't unregister ISDN layer 2 error(%d)\n", err); } - if(isdnl2.ilist) { + if(!list_empty(&isdnl2.ilist)) { printk(KERN_WARNING "mISDNl2 l2 list not empty\n"); - while(isdnl2.ilist) - release_l2(isdnl2.ilist); + list_for_each_entry_safe(l2, nl2, &isdnl2.ilist, list) + release_l2(l2); } TEIFree(); mISDN_FsmFree(&l2fsm); diff --git a/drivers/isdn/hardware/mISDN/layer2.h b/drivers/isdn/hardware/mISDN/layer2.h index 032e01c..9b87395 100644 --- a/drivers/isdn/hardware/mISDN/layer2.h +++ b/drivers/isdn/hardware/mISDN/layer2.h @@ -30,8 +30,7 @@ typedef struct _laddr { } laddr_t; typedef struct _layer2 { - struct _layer2 *prev; - struct _layer2 *next; + struct list_head list; int sapi; int tei; laddr_t addr; diff --git a/drivers/isdn/hardware/mISDN/layer3.c b/drivers/isdn/hardware/mISDN/layer3.c index e2c0e73..9924433 100644 --- a/drivers/isdn/hardware/mISDN/layer3.c +++ b/drivers/isdn/hardware/mISDN/layer3.c @@ -254,26 +254,22 @@ no_l3_proto_spec(struct PStack *st, isdn_ctrl *ic) l3_process_t *getl3proc(layer3_t *l3, int cr) { - l3_process_t *p = l3->proc; - - while (p) + l3_process_t *p; + + list_for_each_entry(p, &l3->plist, list) if (p->callref == cr) return (p); - else - p = p->next; return (NULL); } l3_process_t *getl3proc4id(layer3_t *l3, u_int id) { - l3_process_t *p = l3->proc; + l3_process_t *p; - while (p) + list_for_each_entry(p, &l3->plist, list) if (p->id == id) return (p); - else - p = p->next; return (NULL); } @@ -324,7 +320,7 @@ l3_process_t p->callref = cr; p->n303 = n303; L3InitTimer(p, &p->timer); - APPEND_TO_LIST(p, l3->proc); + list_add_tail(&p->list, &l3->plist); return (p); }; @@ -337,10 +333,10 @@ release_l3_process(l3_process_t *p) return; l3 = p->l3; mISDN_l3up(p, CC_RELEASE_CR | INDICATION, NULL); - REMOVE_FROM_LISTBASE(p, l3->proc); + list_del(&p->list); StopAllL3Timer(p); kfree(p); - if (!l3->proc && !test_bit(FLG_PTP, &l3->Flag)) { + if (list_empty(&l3->plist) && !test_bit(FLG_PTP, &l3->Flag)) { if (l3->debug) l3_debug(l3, "release_l3_process: last process"); if (!skb_queue_len(&l3->squeue)) { @@ -357,15 +353,10 @@ release_l3_process(l3_process_t *p) static void l3ml3p(layer3_t *l3, int pr) { - l3_process_t *p = l3->proc; - l3_process_t *np; + l3_process_t *p, *np; - while (p) { - /* p might be kfreed under us, so we need to save where we want to go on */ - np = p->next; + list_for_each_entry_safe(p, np, &l3->plist, list) l3->p_mgr(p, pr, NULL); - p = np; - } } int @@ -419,7 +410,7 @@ lc_connect(struct FsmInst *fi, int event, void *arg) dev_kfree_skb(skb); dequeued++; } - if ((!l3->proc) && dequeued) { + if (list_empty(&l3->plist) && dequeued) { if (l3->debug) l3m_debug(fi, "lc_connect: release link"); mISDN_FsmEvent(&l3->l3m, EV_RELEASE_REQ, NULL); @@ -441,7 +432,7 @@ lc_connected(struct FsmInst *fi, int event, void *arg) dev_kfree_skb(skb); dequeued++; } - if ((!l3->proc) && dequeued) { + if (list_empty(&l3->plist) && dequeued) { if (l3->debug) l3m_debug(fi, "lc_connected: release link"); mISDN_FsmEvent(&l3->l3m, EV_RELEASE_REQ, NULL); @@ -558,7 +549,7 @@ l3_msg(layer3_t *l3, u_int pr, int dinfo, int len, void *arg) void init_l3(layer3_t *l3) { - l3->proc = NULL; + INIT_LIST_HEAD(&l3->plist); l3->global = NULL; l3->dummy = NULL; l3->entity = MISDN_ENTITY_NONE; @@ -578,11 +569,13 @@ init_l3(layer3_t *l3) void release_l3(layer3_t *l3) { + l3_process_t *p, *np; + if (l3->l3m.debug) - printk(KERN_DEBUG "release_l3(%p) proc(%p) global(%p) dummy(%p)\n", - l3, l3->proc, l3->global, l3->dummy); - while (l3->proc) - release_l3_process(l3->proc); + printk(KERN_DEBUG "release_l3(%p) plist(%s) global(%p) dummy(%p)\n", + l3, list_empty(&l3->plist) ? "no" : "yes", l3->global, l3->dummy); + list_for_each_entry_safe(p, np, &l3->plist, list) + release_l3_process(p); if (l3->global) { StopAllL3Timer(l3->global); kfree(l3->global); diff --git a/drivers/isdn/hardware/mISDN/layer3.h b/drivers/isdn/hardware/mISDN/layer3.h index a8a0af2..9d74394 100644 --- a/drivers/isdn/hardware/mISDN/layer3.h +++ b/drivers/isdn/hardware/mISDN/layer3.h @@ -35,8 +35,7 @@ typedef struct _L3Timer { } L3Timer_t; typedef struct _l3_process { - struct _l3_process *prev; - struct _l3_process *next; + struct list_head list; struct _layer3 *l3; int callref; int state; @@ -49,14 +48,13 @@ typedef struct _l3_process { } l3_process_t; typedef struct _layer3 { - struct _layer3 *prev; - struct _layer3 *next; + struct list_head list; struct FsmInst l3m; struct FsmTimer l3m_timer; int entity; int pid_cnt; int next_id; - l3_process_t *proc; + struct list_head plist; l3_process_t *global; l3_process_t *dummy; int (*p_mgr)(l3_process_t *, u_int, void *); diff --git a/drivers/isdn/hardware/mISDN/m_capi.h b/drivers/isdn/hardware/mISDN/m_capi.h index 9a18efc..c16be19 100755 --- a/drivers/isdn/hardware/mISDN/m_capi.h +++ b/drivers/isdn/hardware/mISDN/m_capi.h @@ -148,11 +148,10 @@ typedef struct FacConfParm FacConfParm_t; // --------------------------------------------------------------------------- struct _PLInst { - PLInst_t *prev; - PLInst_t *next; - u_int state; - mISDNstack_t *st; - mISDNinstance_t inst; + struct list_head list; + u_int state; + mISDNstack_t *st; + mISDNinstance_t inst; }; struct _ConfQueue { @@ -175,11 +174,10 @@ struct Bprotocol { // --------------------------------------------------------------------------- struct _Controller { - struct _Controller *prev; - struct _Controller *next; + struct list_head list; mISDNinstance_t inst; int nr_bc; - PLInst_t *linklist; + struct list_head linklist; struct capi_ctr *ctrl; __u32 addr; int entity; diff --git a/drivers/isdn/hardware/mISDN/sedl_fax.c b/drivers/isdn/hardware/mISDN/sedl_fax.c index 3c5c833..9245957 100644 --- a/drivers/isdn/hardware/mISDN/sedl_fax.c +++ b/drivers/isdn/hardware/mISDN/sedl_fax.c @@ -109,8 +109,7 @@ const char *Sedlbauer_Types[] = /* data struct */ typedef struct _sedl_fax { - struct _sedl_fax *prev; - struct _sedl_fax *next; + struct list_head list; void *pdev; u_int subtyp; u_int irq; @@ -582,7 +581,7 @@ release_card(sedl_fax *card) { mISDN_free_dch(&card->dch); speedfax.ctrl(card->dch.inst.up.peer, MGR_DISCONNECT | REQUEST, &card->dch.inst.up); speedfax.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL); - REMOVE_FROM_LISTBASE(card, ((sedl_fax *)speedfax.ilist)); + list_del(&card->list); unlock_dev(card); if (card->subtyp == SEDL_SPEEDFAX_ISA) { pnp_disable_dev(card->pdev); @@ -597,7 +596,7 @@ release_card(sedl_fax *card) { static int speedfax_manager(void *data, u_int prim, void *arg) { - sedl_fax *card = speedfax.ilist; + sedl_fax *card; mISDNinstance_t *inst=data; int channel = -1; struct sk_buff *skb; @@ -610,7 +609,7 @@ speedfax_manager(void *data, u_int prim, void *arg) { prim, arg); return(-EINVAL); } - while(card) { + list_for_each_entry(card, &speedfax.ilist, list) { if (&card->dch.inst == inst) { channel = 2; break; @@ -623,7 +622,6 @@ speedfax_manager(void *data, u_int prim, void *arg) { channel = 1; break; } - card = card->next; } if (channel<0) { printk(KERN_ERR "speedfax_manager no channel data %p prim %x arg %p\n", @@ -731,7 +729,7 @@ static int __devinit setup_instance(sedl_fax *card) kfree(card); return(-EINVAL); } - APPEND_TO_LIST(card, ((sedl_fax *)speedfax.ilist)); + list_add_tail(&card->list, &speedfax.ilist); card->dch.debug = debug; lock_HW_init(&card->lock); card->dch.inst.lock = lock_dev; @@ -759,7 +757,7 @@ static int __devinit setup_instance(sedl_fax *card) mISDN_free_dch(&card->dch); mISDN_free_bch(&card->bch[1]); mISDN_free_bch(&card->bch[0]); - REMOVE_FROM_LISTBASE(card, ((sedl_fax *)speedfax.ilist)); + list_del(&card->list); kfree(card); return(err); } @@ -825,6 +823,7 @@ static int __devinit sedlpci_probe(struct pci_dev *pdev, const struct pci_device return(err); } +#if defined(CONFIG_PNP) #ifdef NEW_ISAPNP static int __devinit sedlpnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) #else @@ -864,6 +863,7 @@ static int __devinit sedlpnp_probe(struct pci_dev *pdev, const struct isapnp_dev pnp_set_drvdata(pdev, NULL); return(err); } +#endif /* CONFIG_PNP */ static void __devexit sedl_remove_pci(struct pci_dev *pdev) { @@ -875,6 +875,7 @@ static void __devexit sedl_remove_pci(struct pci_dev *pdev) printk(KERN_WARNING "%s: drvdata allready removed\n", __FUNCTION__); } +#if defined(CONFIG_PNP) #ifdef NEW_ISAPNP static void __devexit sedl_remove_pnp(struct pnp_dev *pdev) #else @@ -888,6 +889,7 @@ static void __devexit sedl_remove_pnp(struct pci_dev *pdev) else printk(KERN_WARNING "%s: drvdata allready removed\n", __FUNCTION__); } +#endif static struct pci_device_id sedlpci_ids[] __devinitdata = { { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100, PCI_SUBVENDOR_SPEEDFAX_PYRAMID, PCI_SUB_ID_SEDLBAUER, @@ -905,6 +907,7 @@ static struct pci_driver sedlpci_driver = { id_table: sedlpci_ids, }; +#if defined(CONFIG_PNP) #ifdef NEW_ISAPNP static struct pnp_device_id sedlpnp_ids[] __devinitdata = { { @@ -930,6 +933,7 @@ static struct isapnp_driver sedlpnp_driver = { remove: __devexit_p(sedl_remove_pnp), id_table: sedlpnp_ids, }; +#endif /* CONFIG_PNP */ static int __init Speedfax_init(void) { @@ -938,6 +942,7 @@ static int __init Speedfax_init(void) #ifdef MODULE speedfax.owner = THIS_MODULE; #endif + INIT_LIST_HEAD(&speedfax.ilist); speedfax.name = SpeedfaxName; speedfax.own_ctrl = speedfax_manager; speedfax.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0; @@ -948,9 +953,6 @@ static int __init Speedfax_init(void) speedfax.BPROTO.protocol[2] = ISDN_PID_L2_B_TRANS | ISDN_PID_L2_B_T30; - speedfax.prev = NULL; - speedfax.next = NULL; - if ((err = mISDN_register(&speedfax))) { printk(KERN_ERR "Can't register Speedfax error(%d)\n", err); return(err); @@ -959,11 +961,11 @@ static int __init Speedfax_init(void) if (err < 0) goto out; pci_nr_found = err; - +#if defined(CONFIG_PNP) err = pnp_register_driver(&sedlpnp_driver); if (err < 0) goto out_unregister_pci; - +#endif #if !defined(CONFIG_HOTPLUG) || defined(MODULE) if (pci_nr_found + err == 0) { err = -ENODEV; @@ -974,7 +976,9 @@ static int __init Speedfax_init(void) #if !defined(CONFIG_HOTPLUG) || defined(MODULE) out_unregister_isapnp: +#if defined(CONFIG_PNP) pnp_unregister_driver(&sedlpnp_driver); +#endif #endif out_unregister_pci: pci_unregister_driver(&sedlpci_driver); @@ -984,16 +988,20 @@ static int __init Speedfax_init(void) static void __exit Speedfax_cleanup(void) { - int err; + int err; + sedl_fax *card, *next; + if ((err = mISDN_unregister(&speedfax))) { printk(KERN_ERR "Can't unregister Speedfax PCI error(%d)\n", err); } - while(speedfax.ilist) { + list_for_each_entry_safe(card, next, &speedfax.ilist, list) { printk(KERN_ERR "Speedfax PCI card struct not empty refs %d\n", speedfax.refcnt); - release_card(speedfax.ilist); + release_card(card); } +#if defined(CONFIG_PNP) pnp_unregister_driver(&sedlpnp_driver); +#endif pci_unregister_driver(&sedlpci_driver); } diff --git a/drivers/isdn/hardware/mISDN/stack.c b/drivers/isdn/hardware/mISDN/stack.c index 6c2fc7a..ba49fa4 100644 --- a/drivers/isdn/hardware/mISDN/stack.c +++ b/drivers/isdn/hardware/mISDN/stack.c @@ -8,18 +8,16 @@ #include "core.h" -mISDNstack_t *mISDN_stacklist = NULL; -mISDNinstance_t *mISDN_instlist = NULL; +LIST_HEAD(mISDN_stacklist); +LIST_HEAD(mISDN_instlist); int get_stack_cnt(void) { int cnt = 0; - mISDNstack_t *st = mISDN_stacklist; + mISDNstack_t *st; - while(st) { + list_for_each_entry(st, &mISDN_stacklist, list) cnt++; - st = st->next; - } return(cnt); } @@ -44,20 +42,16 @@ get_stack_info(iframe_t *frm) { memcpy(&si->pid, &st->pid, sizeof(mISDN_pid_t)); memcpy(&si->para, &st->para, sizeof(mISDN_stPara_t)); si->instcnt = 0; - lay = st->lstack; - while(lay) { + list_for_each_entry(lay, &st->layerlist, list) { if (lay->inst) { si->inst[si->instcnt] = lay->inst->id; si->instcnt++; } - lay = lay->next; } si->childcnt = 0; - cst = st->child; - while(cst) { + list_for_each_entry(cst, &st->childlist, list) { si->child[si->childcnt] = cst->id; si->childcnt++; - cst = cst->next; } frm->len = sizeof(stack_info_t); if (si->childcnt>2) @@ -67,18 +61,19 @@ get_stack_info(iframe_t *frm) { static int get_free_stackid(mISDNstack_t *mst, int flag) { - u_int id=1; + u_int id=1, found; mISDNstack_t *st; if (!mst) { while(id<127) { - st = mISDN_stacklist; - while (st) { - if (st->id == id) + found = 0; + list_for_each_entry(st, &mISDN_stacklist, list) { + if (st->id == id) { + found++; break; - st = st->next; + } } - if (st) + if (found) id++; else return(id); @@ -86,27 +81,29 @@ get_free_stackid(mISDNstack_t *mst, int flag) { } else if (flag & FLG_CLONE_STACK) { id = mst->id | FLG_CLONE_STACK; while(id < CLONE_ID_MAX) { + found = 0; id += CLONE_ID_INC; - st = mISDN_stacklist; - while (st) { - if (st->id == id) + list_for_each_entry(st, &mISDN_stacklist, list) { + if (st->id == id) { + found++; break; - st = st->next; + } } - if (!st) + if (!found) return(id); } } else if (flag & FLG_CHILD_STACK) { id = mst->id | FLG_CHILD_STACK; while(id < CHILD_ID_MAX) { id += CHILD_ID_INC; - st = mst->child; - while (st) { - if (st->id == id) + found = 0; + list_for_each_entry(st, &mst->childlist, list) { + if (st->id == id) { + found++; break; - st = st->next; + } } - if (!st) + if (!found) return(id); } } @@ -116,22 +113,19 @@ get_free_stackid(mISDNstack_t *mst, int flag) { mISDNstack_t * get_stack4id(u_int id) { - mISDNstack_t *cst, *st = mISDN_stacklist; + mISDNstack_t *cst, *st; if (core_debug & DEBUG_CORE_FUNC) printk(KERN_DEBUG "get_stack4id(%x)\n", id); if (!id) /* 0 isn't a valid id */ return(NULL); - while(st) { + list_for_each_entry(st, &mISDN_stacklist, list) { if (id == st->id) return(st); - cst = st->child; - while (cst) { + list_for_each_entry(cst, &st->childlist, list) { if (cst->id == id) return(cst); - cst = cst->next; } - st = st->next; } return(NULL); } @@ -146,14 +140,12 @@ getlayer4lay(mISDNstack_t *st, int layermask) int_error(); return(NULL); } - layer = st->lstack; - while(layer) { + list_for_each_entry(layer, &st->layerlist, list) { inst = layer->inst; if(inst && (inst->pid.layermask & layermask)) - break; - layer = layer->next; + return(layer); } - return(layer); + return(NULL); } mISDNinstance_t * @@ -173,8 +165,7 @@ get_instance(mISDNstack_t *st, int layer_nr, int protocol) int_errtxt("lnr %d", layer_nr); return(NULL); } - layer = st->lstack; - while(layer) { + list_for_each_entry(layer, &st->layerlist, list) { inst = layer->inst; if (inst) { if (core_debug & DEBUG_CORE_FUNC) @@ -186,11 +177,10 @@ get_instance(mISDNstack_t *st, int layer_nr, int protocol) goto out; inst = NULL; } - if (layer == layer->next) { + if (list_empty(&layer->list)) { int_errtxt("deadloop layer %p", layer); return(NULL); } - layer = layer->next; } out: return(inst); @@ -199,13 +189,11 @@ out: mISDNinstance_t * get_instance4id(u_int id) { - mISDNinstance_t *inst = mISDN_instlist; + mISDNinstance_t *inst; - while(inst) { + list_for_each_entry(inst, &mISDN_instlist, list) if (inst->id == id) return(inst); - inst = inst->next; - } return(NULL); } @@ -231,22 +219,16 @@ insertlayer(mISDNstack_t *st, mISDNlayer_t *layer, int layermask) int_error(); return(-EINVAL); } - item = st->lstack; - if (!item) { - st->lstack = layer; + if (list_empty(&st->layerlist)) { + list_add(&layer->list, &st->layerlist); } else { - while(item) { + list_for_each_entry(item, &st->layerlist, list) { if (layermask < get_layermask(item)) { - INSERT_INTO_LIST(layer, item, st->lstack); + list_add_tail(&layer->list, &item->list); return(0); - } else { - if (!item->next) - break; } - item = item->next; } - item->next = layer; - layer->prev = item; + list_add_tail(&layer->list, &st->layerlist); } return(0); } @@ -264,6 +246,8 @@ 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); if (!master) { if (inst && inst->st) { newst->id = get_free_stackid(inst->st, FLG_CLONE_STACK); @@ -275,9 +259,9 @@ new_stack(mISDNstack_t *master, mISDNinstance_t *inst) } newst->mgr = inst; if (master) { - APPEND_TO_LIST(newst, master->child); + list_add_tail(&newst->list, &master->childlist); } else { - APPEND_TO_LIST(newst, mISDN_stacklist); + list_add_tail(&newst->list, &mISDN_stacklist); } if (core_debug & DEBUG_CORE_FUNC) printk(KERN_DEBUG "Stack id %x added\n", newst->id); @@ -291,10 +275,10 @@ static int release_layers(mISDNstack_t *st, u_int prim) { mISDNinstance_t *inst; - mISDNlayer_t *layer; + mISDNlayer_t *layer, *nl; int cnt = 0; - while((layer = st->lstack)) { + list_for_each_entry_safe(layer, nl, &st->layerlist, list) { inst = layer->inst; if (inst) { if (core_debug & DEBUG_CORE_FUNC) @@ -303,10 +287,10 @@ release_layers(mISDNstack_t *st, u_int prim) inst->name, inst->pid.layermask); inst->obj->own_ctrl(inst, prim, NULL); } - REMOVE_FROM_LISTBASE(layer, st->lstack); + list_del(&layer->list); kfree(layer); if (cnt++ > 1000) { - int_errtxt("release_layers st(%p)", st); + int_errtxt("release_layers endless loop st(%p)", st); return(-EINVAL); } } @@ -317,17 +301,15 @@ int do_for_all_layers(mISDNstack_t *st, u_int prim, void *arg) { mISDNinstance_t *inst; - mISDNlayer_t *layer; + mISDNlayer_t *layer, *nl; int cnt = 0; if (!st) { int_error(); return(-EINVAL); } - layer = st->lstack; - while(layer) { + list_for_each_entry_safe(layer, nl, &st->layerlist, list) { inst = layer->inst; - layer = layer->next; if (inst) { if (core_debug & DEBUG_CORE_FUNC) printk(KERN_DEBUG "%s: st(%p) inst(%p):%x %s prim(%x) arg(%p)\n", @@ -335,7 +317,7 @@ do_for_all_layers(mISDNstack_t *st, u_int prim, void *arg) inst->obj->own_ctrl(inst, prim, arg); } if (cnt++ > 1000) { - int_errtxt("release_layers st(%p)", st); + int_errtxt("do_for_all_layers endless loop st(%p)", st); return(-EINVAL); } } @@ -382,66 +364,55 @@ change_stack_para(mISDNstack_t *st, u_int prim, mISDN_stPara_t *stpara) int release_stack(mISDNstack_t *st) { int err; - mISDNstack_t *cst; + mISDNstack_t *cst, *nst; if (core_debug & DEBUG_CORE_FUNC) printk(KERN_DEBUG "%s: st(%p)\n", __FUNCTION__, st); - while (st->child) { - cst = st->child; + 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); return(err); } - REMOVE_FROM_LISTBASE(cst, st->child); + list_del(&cst->list); kfree(cst); } if ((err = release_layers(st, MGR_RELEASE | INDICATION))) { printk(KERN_WARNING "release_stack err(%d)\n", err); return(err); } - REMOVE_FROM_LISTBASE(st, mISDN_stacklist); + list_del(&st->list); kfree(st); if (core_debug & DEBUG_CORE_FUNC) - printk(KERN_DEBUG "%s: mISDN_stacklist(%p)\n", __FUNCTION__, mISDN_stacklist); + printk(KERN_DEBUG "%s: mISDN_stacklist(%p<-%p->%p)\n", __FUNCTION__, + mISDN_stacklist.prev, &mISDN_stacklist, mISDN_stacklist.next); return(0); } void release_stacks(mISDNobject_t *obj) { mISDNstack_t *st, *tmp; - mISDNlayer_t *layer; - mISDNinstance_t *inst; + mISDNlayer_t *layer, *ltmp; int rel; - st = mISDN_stacklist; if (core_debug & DEBUG_CORE_FUNC) printk(KERN_DEBUG "%s: obj(%p) %s\n", __FUNCTION__, obj, obj->name); - while (st) { + list_for_each_entry_safe(st, tmp, &mISDN_stacklist, list) { rel = 0; - layer = st->lstack; if (core_debug & DEBUG_CORE_FUNC) - printk(KERN_DEBUG "%s: st(%p) l(%p)\n", - __FUNCTION__, st, layer); - while(layer) { - inst = layer->inst; - if (inst) { - if (core_debug & DEBUG_CORE_FUNC) - printk(KERN_DEBUG "%s: inst(%p)\n", - __FUNCTION__, inst); - if (inst->obj == obj) - rel++; - } - layer = layer->next; + printk(KERN_DEBUG "%s: st(%p)\n", + __FUNCTION__, st); + list_for_each_entry_safe(layer, ltmp, &st->layerlist, list) { + 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) + rel++; } - if (rel) { - tmp = st->next; + if (rel) release_stack(st); - st = tmp; - } else - st = st->next; } if (obj->refcnt) printk(KERN_WARNING "release_stacks obj %s refcnt is %d\n", @@ -451,24 +422,22 @@ release_stacks(mISDNobject_t *obj) { static void get_free_instid(mISDNstack_t *st, mISDNinstance_t *inst) { - mISDNinstance_t *il = mISDN_instlist; + mISDNinstance_t *il; inst->id = mISDN_get_lowlayer(inst->pid.layermask)<<20; inst->id |= FLG_INSTANCE; if (st) { inst->id |= st->id; } else { - while(il) { + list_for_each_entry(il, &mISDN_instlist, list) { if (il->id == inst->id) { if ((inst->id & IF_INSTMASK) >= INST_ID_MAX) { inst->id = 0; return; } inst->id += INST_ID_INC; - il = mISDN_instlist; - continue; + il = list_entry(mISDN_instlist.next, mISDNinstance_t, list); } - il = il->next; } } } @@ -515,7 +484,7 @@ register_layer(mISDNstack_t *st, mISDNinstance_t *inst) { if (!inst->id) { int_errtxt("no free inst->id for layer %x", inst->pid.layermask); if (st && layer) { - REMOVE_FROM_LISTBASE(layer, st->lstack); + list_del(&layer->list); kfree(layer); } return(-EINVAL); @@ -523,7 +492,7 @@ register_layer(mISDNstack_t *st, mISDNinstance_t *inst) { inst->st = st; if (refinc) inst->obj->refcnt++; - APPEND_TO_LIST(inst, mISDN_instlist); + list_add_tail(&inst->list, &mISDN_instlist); return(0); } @@ -550,12 +519,12 @@ unregister_instance(mISDNinstance_t *inst) { if (inst->st && (inst->st->mgr != inst)) inst->st = NULL; } - REMOVE_FROM_LISTBASE(inst, mISDN_instlist); - inst->prev = inst->next = 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)\n", __FUNCTION__, mISDN_instlist); + printk(KERN_DEBUG "%s: mISDN_instlist(%p<-%p->%p)\n", __FUNCTION__, + mISDN_instlist.prev, &mISDN_instlist, mISDN_instlist.next); return(0); } @@ -588,7 +557,7 @@ set_stack(mISDNstack_t *st, mISDN_pid_t *pid) int err; u_char *pbuf = NULL; mISDNinstance_t *inst; - mISDNlayer_t *hl; + mISDNlayer_t *hl, *hln; if (!st || !pid) { int_error(); @@ -624,8 +593,10 @@ set_stack(mISDNstack_t *st, mISDN_pid_t *pid) } mISDN_RemoveUsedPID(pid, &inst->pid); } - hl = st->lstack; - while(hl && hl->next) { + + list_for_each_entry_safe(hl, hln, &st->layerlist, list) { + if (hl->list.next == &st->layerlist) + break; if (!hl->inst) { int_error(); return(-EINVAL); @@ -639,8 +610,7 @@ set_stack(mISDNstack_t *st, mISDN_pid_t *pid) return(-EINVAL); } hl->inst->obj->own_ctrl(hl->inst, MGR_CONNECT | REQUEST, - hl->next->inst); - hl = hl->next; + hln->inst); } st->mgr->obj->own_ctrl(st->mgr, MGR_SETSTACK |CONFIRM, NULL); return(0); diff --git a/drivers/isdn/hardware/mISDN/udevice.c b/drivers/isdn/hardware/mISDN/udevice.c index 983d88e..1ac7154 100644 --- a/drivers/isdn/hardware/mISDN/udevice.c +++ b/drivers/isdn/hardware/mISDN/udevice.c @@ -10,7 +10,6 @@ #include #include #include -#include #include "core.h" #define MAX_HEADER_LEN 4 @@ -23,8 +22,7 @@ typedef struct _devicelayer { - struct _devicelayer *prev; - struct _devicelayer *next; + struct list_head list; mISDNdevice_t *dev; mISDNinstance_t inst; mISDNinstance_t *slave; @@ -36,16 +34,14 @@ typedef struct _devicelayer { } devicelayer_t; typedef struct _devicestack { - struct _devicestack *prev; - struct _devicestack *next; + struct list_head list; mISDNdevice_t *dev; mISDNstack_t *st; int extentions; } devicestack_t; typedef struct _mISDNtimer { - struct _mISDNtimer *prev; - struct _mISDNtimer *next; + struct list_head list; struct _mISDNdevice *dev; struct timer_list tl; int id; @@ -57,7 +53,7 @@ typedef struct entity_item { int entity; } entity_item_t; -static mISDNdevice_t *mISDN_devicelist = NULL; +static LIST_HEAD(mISDN_devicelist); static rwlock_t mISDN_device_lock = RW_LOCK_UNLOCKED; static mISDNobject_t udev_obj; @@ -76,14 +72,17 @@ static int mISDN_wdata(mISDNdevice_t *dev); static mISDNdevice_t * get_mISDNdevice4minor(int minor) { - mISDNdevice_t *dev = mISDN_devicelist; + mISDNdevice_t *dev; - while(dev) { - if (dev->minor == minor) - break; - dev = dev->next; + read_lock(&mISDN_device_lock); + list_for_each_entry(dev, &mISDN_devicelist, list) { + if (dev->minor == minor) { + read_unlock(&mISDN_device_lock); + return(dev); + } } - return(dev); + read_unlock(&mISDN_device_lock); + return(NULL); } static __inline__ void @@ -252,69 +251,65 @@ mISDN_rdata(mISDNdevice_t *dev, iframe_t *iff, int use_value) { } static devicelayer_t -*get_devlayer(mISDNdevice_t *dev, int addr) { - devicelayer_t *dl = dev->layer; +*get_devlayer(mISDNdevice_t *dev, int addr) { + devicelayer_t *dl; if (device_debug & DEBUG_MGR_FUNC) printk(KERN_DEBUG "%s: addr:%x\n", __FUNCTION__, addr); - while(dl) { + list_for_each_entry(dl, &dev->layerlist, list) { // 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)) - break; - dl = dl->next; + return(dl); } - return(dl); + return(NULL); } static devicestack_t *get_devstack(mISDNdevice_t *dev, int addr) { - devicestack_t *ds = dev->stack; + devicestack_t *ds; if (device_debug & DEBUG_MGR_FUNC) printk(KERN_DEBUG "%s: addr:%x\n", __FUNCTION__, addr); - while(ds) { + list_for_each_entry(ds, &dev->stacklist, list) { if (ds->st && (ds->st->id == (u_int)addr)) - break; - ds = ds->next; + return(ds); } - return(ds); + return(NULL); } static mISDNtimer_t -*get_devtimer(mISDNdevice_t *dev, int id) +*get_devtimer(mISDNdevice_t *dev, int id) { - mISDNtimer_t *ht = dev->timer; + mISDNtimer_t *ht; if (device_debug & DEBUG_DEV_TIMER) printk(KERN_DEBUG "%s: dev:%p id:%x\n", __FUNCTION__, dev, id); - while(ht) { + list_for_each_entry(ht, &dev->timerlist, list) { if (ht->id == id) - break; - ht = ht->next; + return(ht); } - return(ht); + return(NULL); } static int stack_inst_flg(mISDNdevice_t *dev, mISDNstack_t *st, int bit, int clear) { - int ret = -1; - devicelayer_t *dl = dev->layer; + int ret; + devicelayer_t *dl; - while(dl) { + list_for_each_entry(dl, &dev->layerlist, list) { if (dl->inst.st == st) { if (clear) ret = test_and_clear_bit(bit, &dl->Flags); else ret = test_and_set_bit(bit, &dl->Flags); - break; + return(ret); } - dl = dl->next; } - return(ret); + return(-1); } static int @@ -349,7 +344,8 @@ new_devstack(mISDNdevice_t *dev, stack_info_t *si) nds->dev = dev; if (si->extentions & EXT_STACK_CLONE) { // memcpy(&inst.st->pid, &st->pid, sizeof(mISDN_pid_t)); - inst.st->child = st->child; + // FIXME that is a ugly idea, but I don't have a better one + inst.st->childlist.prev = &st->childlist; } else { memcpy(&inst.st->pid, &si->pid, sizeof(mISDN_pid_t)); } @@ -357,7 +353,7 @@ new_devstack(mISDNdevice_t *dev, stack_info_t *si) inst.st->extentions |= si->extentions; inst.st->mgr = get_instance4id(si->mgr); nds->st = inst.st; - APPEND_TO_LIST(nds, dev->stack); + list_add_tail(&nds->list, &dev->stacklist); return(inst.st->id); } @@ -453,7 +449,7 @@ create_layer(mISDNdevice_t *dev, layer_info_t *linfo, int *adr) nl->inst.up.owner = &nl->inst; nl->inst.obj = &udev_obj; nl->inst.data = nl; - APPEND_TO_LIST(nl, dev->layer); + list_add_tail(&nl->list, &dev->layerlist); nl->inst.obj->ctrl(st, MGR_REGLAYER | INDICATION, &nl->inst); nl->iaddr = nl->inst.id; *adr++ = nl->iaddr; @@ -492,7 +488,10 @@ remove_if(devicelayer_t *dl, int stat) { memcpy(phif, shif, sizeof(mISDNif_t)); memset(shif, 0, sizeof(mISDNif_t)); } - REMOVE_FROM_LIST(hif); + if (hif->predecessor) + hif->predecessor->clone = hif->clone; + if (hif->clone) + hif->clone->predecessor = hif->predecessor; return(err); } @@ -514,10 +513,10 @@ del_stack(devicestack_t *ds) return(-EINVAL); if (ds->st) { if (ds->extentions & EXT_STACK_CLONE) - ds->st->child = NULL; + INIT_LIST_HEAD(&ds->st->childlist); udev_obj.ctrl(ds->st, MGR_DELSTACK | REQUEST, NULL); } - REMOVE_FROM_LISTBASE(ds, dev->stack); + list_del(&ds->list); kfree(ds); return(0); } @@ -529,8 +528,8 @@ del_layer(devicelayer_t *dl) { int i; if (device_debug & DEBUG_MGR_FUNC) { - printk(KERN_DEBUG "%s: dl(%p) inst(%p) LM(%x) dev(%p) nexti(%p)\n", - __FUNCTION__, dl, inst, inst->pid.layermask, dev, inst->next); + printk(KERN_DEBUG "%s: dl(%p) inst(%p) LM(%x) dev(%p)\n", + __FUNCTION__, dl, inst, inst->pid.layermask, dev); printk(KERN_DEBUG "%s: iaddr %x inst %s slave %p\n", __FUNCTION__, dl->iaddr, inst->name, dl->slave); } @@ -566,7 +565,7 @@ del_layer(devicelayer_t *dl) { MGR_DISCONNECT | REQUEST, &inst->down); } dl->iaddr = 0; - REMOVE_FROM_LISTBASE(dl, dev->layer); + list_del(&dl->list); udev_obj.ctrl(inst, MGR_UNREGLAYER | REQUEST, NULL); if (test_and_clear_bit(FLG_MGR_OWNSTACK, &dl->Flags)) { if (dl->inst.st) { @@ -859,14 +858,12 @@ dev_init_timer(mISDNdevice_t *dev, iframe_t *iff) ht = kmalloc(sizeof(mISDNtimer_t), GFP_ATOMIC); if (!ht) return(-ENOMEM); - ht->prev = NULL; - ht->next = NULL; ht->dev = dev; ht->id = iff->addr; ht->tl.data = (long) ht; ht->tl.function = (void *) dev_expire_timer; init_timer(&ht->tl); - APPEND_TO_LIST(ht, dev->timer); + list_add_tail(&ht->list, &dev->timerlist); if (device_debug & DEBUG_DEV_TIMER) printk(KERN_DEBUG "%s: new(%x)\n", __FUNCTION__, ht->id); } else if (device_debug & DEBUG_DEV_TIMER) @@ -933,6 +930,16 @@ dev_del_timer(mISDNdevice_t *dev, iframe_t *iff) return(0); } +static void +dev_free_timer(mISDNtimer_t *ht) +{ + if (device_debug & DEBUG_DEV_TIMER) + printk(KERN_DEBUG "%s: timer(%x)\n", __FUNCTION__, ht->id); + del_timer(&ht->tl); + list_del(&ht->list); + kfree(ht); +} + static int dev_remove_timer(mISDNdevice_t *dev, int id) { @@ -943,11 +950,7 @@ dev_remove_timer(mISDNdevice_t *dev, int id) printk(KERN_WARNING "%s: no timer(%x)\n", __FUNCTION__, id); return(-ENODEV); } - if (device_debug & DEBUG_DEV_TIMER) - printk(KERN_DEBUG "%s: timer(%x)\n", __FUNCTION__, ht->id); - del_timer(&ht->tl); - REMOVE_FROM_LISTBASE(ht, dev->timer); - kfree(ht); + dev_free_timer(ht); return(0); } @@ -1532,9 +1535,12 @@ init_device(u_int minor) { init_waitqueue_head(&dev->rport.procq); init_waitqueue_head(&dev->wport.procq); init_MUTEX(&dev->io_sema); + INIT_LIST_HEAD(&dev->layerlist); + INIT_LIST_HEAD(&dev->stacklist); + INIT_LIST_HEAD(&dev->timerlist); INIT_LIST_HEAD(&dev->entitylist); write_lock_irqsave(&mISDN_device_lock, flags); - APPEND_TO_LIST(dev, mISDN_devicelist); + list_add_tail(&dev->list, &mISDN_devicelist); write_unlock_irqrestore(&mISDN_device_lock, flags); } return(dev); @@ -1568,6 +1574,7 @@ get_free_rawdevice(void) int free_device(mISDNdevice_t *dev) { + struct list_head *item, *ni; u_long flags; if (!dev) @@ -1575,25 +1582,24 @@ free_device(mISDNdevice_t *dev) if (device_debug & DEBUG_MGR_FUNC) printk(KERN_DEBUG "%s: dev(%d)\n", __FUNCTION__, dev->minor); /* release related stuff */ - while(dev->layer) - del_layer(dev->layer); - while(dev->stack) - del_stack(dev->stack); - while(dev->timer) - dev_remove_timer(dev, dev->timer->id); + list_for_each_safe(item, ni, &dev->layerlist) + del_layer(list_entry(item, devicelayer_t, list)); + list_for_each_safe(item, ni, &dev->stacklist) + del_stack(list_entry(item, devicestack_t, list)); + list_for_each_safe(item, ni, &dev->timerlist) + dev_free_timer(list_entry(item, mISDNtimer_t, list)); if (dev->rport.buf) vfree(dev->rport.buf); if (dev->wport.buf) vfree(dev->wport.buf); write_lock_irqsave(&mISDN_device_lock, flags); - REMOVE_FROM_LISTBASE(dev, mISDN_devicelist); + list_del(&dev->list); write_unlock_irqrestore(&mISDN_device_lock, flags); if (!list_empty(&dev->entitylist)) { printk(KERN_WARNING "MISDN %s: entitylist not empty\n", __FUNCTION__); - while(!list_empty(&dev->entitylist)) { - struct entity_item *ei; - ei = (struct entity_item *)dev->entitylist.next; - list_del((struct list_head *)ei); + list_for_each_safe(item, ni, &dev->entitylist) { + struct entity_item *ei = list_entry(item, struct entity_item, head); + list_del(item); mISDN_delete_entity(ei->entity); kfree(ei); } @@ -1631,7 +1637,7 @@ mISDN_open(struct inode *ino, struct file *filep) if (!dev->rport.buf) { if (isnew) { write_lock_irqsave(&mISDN_device_lock, flags); - REMOVE_FROM_LISTBASE(dev, mISDN_devicelist); + list_del(&dev->list); write_unlock_irqrestore(&mISDN_device_lock, flags); kfree(dev); } @@ -1652,7 +1658,7 @@ mISDN_open(struct inode *ino, struct file *filep) if (dev->rport.buf) vfree(dev->rport.buf); write_lock_irqsave(&mISDN_device_lock, flags); - REMOVE_FROM_LISTBASE(dev, mISDN_devicelist); + list_del(&dev->list); write_unlock_irqrestore(&mISDN_device_lock, flags); kfree(dev); } @@ -1674,12 +1680,12 @@ mISDN_open(struct inode *ino, struct file *filep) static int mISDN_close(struct inode *ino, struct file *filep) { - mISDNdevice_t *dev = mISDN_devicelist; + mISDNdevice_t *dev, *nd; if (device_debug & DEBUG_DEV_OP) printk(KERN_DEBUG "mISDN: mISDN_close %p %p\n", filep, filep->private_data); read_lock(&mISDN_device_lock); - while (dev) { + list_for_each_entry_safe(dev, nd, &mISDN_devicelist, list) { if (dev == filep->private_data) { if (device_debug & DEBUG_DEV_OP) printk(KERN_DEBUG "mISDN: dev(%d) %p mode %x/%x\n", @@ -1699,7 +1705,6 @@ mISDN_close(struct inode *ino, struct file *filep) free_device(dev); return 0; } - dev = dev->next; } read_unlock(&mISDN_device_lock); printk(KERN_WARNING "mISDN: No private data while closing device\n"); @@ -1941,9 +1946,9 @@ set_if(devicelayer_t *dl, u_int prim, mISDNif_t *hif) static int udev_manager(void *data, u_int prim, void *arg) { mISDNinstance_t *inst = data; - mISDNdevice_t *dev = mISDN_devicelist; - devicelayer_t *dl = NULL; - int err = -EINVAL; + mISDNdevice_t *dev; + devicelayer_t *dl; + int err = -EINVAL; if (device_debug & DEBUG_MGR_FUNC) printk(KERN_DEBUG "udev_manager data:%p prim:%x arg:%p\n", @@ -1951,18 +1956,17 @@ udev_manager(void *data, u_int prim, void *arg) { if (!data) return(-EINVAL); read_lock(&mISDN_device_lock); - while(dev) { - dl = dev->layer; - while(dl) { - if (&dl->inst == inst) + list_for_each_entry(dev, &mISDN_devicelist, list) { + list_for_each_entry(dl, &dev->layerlist, list) { + if (&dl->inst == inst) { + err = 0; break; - dl = dl->next; + } } - if (dl) + if (!err) break; - dev = dev->next; } - if (!dl) { + if (err) { printk(KERN_WARNING "dev_manager prim %x without device layer\n", prim); goto out; } @@ -1987,6 +1991,7 @@ udev_manager(void *data, u_int prim, void *arg) { break; default: printk(KERN_WARNING "dev_manager prim %x not handled\n", prim); + err = -EINVAL; break; } out: @@ -2002,9 +2007,8 @@ int init_mISDNdev (int debug) { udev_obj.DPROTO.protocol[i] = ISDN_PID_ANY; udev_obj.BPROTO.protocol[i] = ISDN_PID_ANY; } + INIT_LIST_HEAD(&udev_obj.ilist); udev_obj.own_ctrl = udev_manager; - udev_obj.prev = NULL; - udev_obj.next = NULL; device_debug = debug; if (register_chrdev(mISDN_MAJOR, "mISDN", &mISDN_fops)) { printk(KERN_WARNING "mISDN: Could not register devices\n"); @@ -2018,13 +2022,12 @@ int init_mISDNdev (int debug) { int free_mISDNdev(void) { int err = 0; - mISDNdevice_t *dev = mISDN_devicelist; + mISDNdevice_t *dev, *nd; - if (mISDN_devicelist) { + if (!list_empty(&mISDN_devicelist)) { printk(KERN_WARNING "mISDN: devices open on remove\n"); - while (dev) { + list_for_each_entry_safe(dev, nd, &mISDN_devicelist, list) { free_device(dev); - dev = mISDN_devicelist; } err = -EBUSY; } diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c index f47c53b..15f4e31 100755 --- a/drivers/isdn/hardware/mISDN/w6692.c +++ b/drivers/isdn/hardware/mISDN/w6692.c @@ -51,8 +51,7 @@ typedef struct _w6692_bc { } w6692_bc; typedef struct _w6692pci { - struct _w6692pci *prev; - struct _w6692pci *next; + struct list_head list; void *pdev; u_int irq; u_int irqcnt; @@ -165,7 +164,7 @@ W6692_new_ph(dchannel_t *dch) para = HW_RESET; while(upif) { if_link(upif, prim, para, 0, NULL, 0); - upif = upif->next; + upif = upif->clone; } upif = &dch->inst.up; /* fall trough */ @@ -198,7 +197,7 @@ W6692_new_ph(dchannel_t *dch) } while(upif) { if_link(upif, prim, para, 0, NULL, 0); - upif = upif->next; + upif = upif->clone; } } @@ -1278,7 +1277,7 @@ release_card(w6692pci *card) mISDN_free_dch(&card->dch); w6692.ctrl(card->dch.inst.up.peer, MGR_DISCONNECT | REQUEST, &card->dch.inst.up); w6692.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL); - REMOVE_FROM_LISTBASE(card, ((w6692pci *)w6692.ilist)); + list_del(&card->list); unlock_dev(card); pci_disable_device(card->pdev); pci_set_drvdata(card->pdev, NULL); @@ -1287,7 +1286,7 @@ release_card(w6692pci *card) static int w6692_manager(void *data, u_int prim, void *arg) { - w6692pci *card = w6692.ilist; + w6692pci *card; mISDNinstance_t *inst = data; struct sk_buff *skb; int channel = -1; @@ -1301,7 +1300,7 @@ w6692_manager(void *data, u_int prim, void *arg) { __FUNCTION__, prim, arg); return(-EINVAL); } - while(card) { + list_for_each_entry(card, &w6692.ilist, list) { if (&card->dch.inst == inst) { channel = 2; break; @@ -1314,7 +1313,6 @@ w6692_manager(void *data, u_int prim, void *arg) { channel = 1; break; } - card = card->next; } if (channel<0) { printk(KERN_WARNING "%s: no channel data %p prim %x arg %p\n", @@ -1420,7 +1418,7 @@ static int __devinit setup_instance(w6692pci *card) int i, err; mISDN_pid_t pid; - APPEND_TO_LIST(card, ((w6692pci *)w6692.ilist)); + list_add_tail(&card->list, &w6692.ilist); card->dch.debug = debug; lock_HW_init(&card->lock); card->dch.inst.lock = lock_dev; @@ -1451,7 +1449,7 @@ static int __devinit setup_instance(w6692pci *card) mISDN_free_dch(&card->dch); mISDN_free_bch(&card->bch[1]); mISDN_free_bch(&card->bch[0]); - REMOVE_FROM_LISTBASE(card, ((w6692pci *)w6692.ilist)); + list_del(&card->list); kfree(card); return(err); } @@ -1567,14 +1565,13 @@ static int __init w6692_init(void) #ifdef MODULE w6692.owner = THIS_MODULE; #endif + INIT_LIST_HEAD(&w6692.ilist); w6692.name = W6692Name; w6692.own_ctrl = w6692_manager; w6692.DPROTO.protocol[0] = ISDN_PID_L0_TE_S0; w6692.BPROTO.protocol[1] = ISDN_PID_L1_B_64TRANS | ISDN_PID_L1_B_64HDLC; w6692.BPROTO.protocol[2] = ISDN_PID_L2_B_TRANS; - w6692.prev = NULL; - w6692.next = NULL; if ((err = mISDN_register(&w6692))) { printk(KERN_ERR "Can't register Winbond W6692 PCI error(%d)\n", err); return(err); @@ -1597,15 +1594,16 @@ static int __init w6692_init(void) static void __exit w6692_cleanup(void) { - int err; + int err; + w6692pci *card, *next; if ((err = mISDN_unregister(&w6692))) { printk(KERN_ERR "Can't unregister Winbond W6692 PCI error(%d)\n", err); } - while(w6692.ilist) { + list_for_each_entry_safe(card, next, &w6692.ilist, list) { printk(KERN_ERR "Winbond W6692 PCI card struct not empty refs %d\n", w6692.refcnt); - release_card(w6692.ilist); + release_card(card); } pci_unregister_driver(&w6692_driver); } diff --git a/drivers/isdn/hardware/mISDN/x25_dte.c b/drivers/isdn/hardware/mISDN/x25_dte.c index 7c1864c..0dfb4f5 100644 --- a/drivers/isdn/hardware/mISDN/x25_dte.c +++ b/drivers/isdn/hardware/mISDN/x25_dte.c @@ -1248,22 +1248,24 @@ MODULE_LICENSE("GPL"); static int dte_manager(void *data, u_int prim, void *arg) { mISDNinstance_t *inst = data; - x25_l3_t *l3_l = x25dte_obj.ilist; + x25_l3_t *l3_l; + int err = -EINVAL; if (debug & DEBUG_L3X25_MGR) printk(KERN_DEBUG "l3x25_manager data:%p prim:%x arg:%p\n", data, prim, arg); if (!data) - return(-EINVAL); - while(l3_l) { - if (&l3_l->inst == inst) + return(err); + list_for_each_entry(l3_l, &x25dte_obj.ilist, list) { + if (&l3_l->inst == inst) { + err = 0; break; - l3_l = l3_l->next; + } } if (prim == (MGR_NEWLAYER | REQUEST)) return(new_l3(data, arg)); - if (!l3_l) { + if (err) { printk(KERN_WARNING "l3x25_manager prim(%x) no instance\n", prim); - return(-EINVAL); + return(err); } switch(prim) { case MGR_NEWENTITY | CONFIRM: @@ -1320,9 +1322,7 @@ x25_dte_init(void) x25dte_obj.name = MName; x25dte_obj.BPROTO.protocol[3] = ISDN_PID_L3_B_X25DTE; x25dte_obj.own_ctrl = dte_manager; - x25dte_obj.prev = NULL; - x25dte_obj.next = NULL; - x25dte_obj.ilist = NULL; + INIT_LIST_HEAD(&x25dte_obj.ilist); if ((err = mISDN_register(&x25dte_obj))) { printk(KERN_ERR "Can't register %s error(%d)\n", MName, err); } else { @@ -1349,15 +1349,16 @@ x25_dte_init(void) static void x25_dte_cleanup(void) { - int err; + x25_l3_t *l3, *nl3; + int err; if ((err = mISDN_unregister(&x25dte_obj))) { printk(KERN_ERR "Can't unregister l3x25 error(%d)\n", err); } - if(x25dte_obj.ilist) { + if(!list_empty(&x25dte_obj.ilist)) { printk(KERN_WARNING "l3x25 inst list not empty\n"); - while(x25dte_obj.ilist) - X25_release_l3(x25dte_obj.ilist); + list_for_each_entry_safe(l3, nl3, &x25dte_obj.ilist, list) + X25_release_l3(l3); } X25_l3_cleanup(); mISDN_FsmFree(&dte_rfsm); diff --git a/drivers/isdn/hardware/mISDN/x25_l3.c b/drivers/isdn/hardware/mISDN/x25_l3.c index 1a2cfc2..2886df5 100644 --- a/drivers/isdn/hardware/mISDN/x25_l3.c +++ b/drivers/isdn/hardware/mISDN/x25_l3.c @@ -273,13 +273,12 @@ X25_reset_channel(x25_channel_t *l3c, struct sk_buff *skb) int X25_restart(x25_l3_t *l3) { - x25_channel_t *l3c = l3->channels; + x25_channel_t *l3c; - while(l3c) { + list_for_each_entry(l3c, &l3->channellist, list) { memcpy(l3c->cause, l3->cause, 2); X25_reset_channel(l3c, NULL); mISDN_FsmEvent(&l3c->x25p, EV_L3_READY, NULL); - l3c = l3c->next; } return(0); } @@ -539,9 +538,7 @@ X25_get_and_test_ps(x25_channel_t *chan, u_char ptype, struct sk_buff *skb) void X25_release_channel(x25_channel_t *l3c) { - x25_l3_t *l3 = l3c->l3; - - REMOVE_FROM_LISTBASE(l3c, l3->channels); + list_del(&l3c->list); if (l3c->ncpi_data) kfree(l3c->ncpi_data); l3c->ncpi_data = NULL; @@ -561,6 +558,7 @@ X25_release_channel(x25_channel_t *l3c) void X25_release_l3(x25_l3_t *l3) { mISDNinstance_t *inst = &l3->inst; + x25_channel_t *ch, *nch; if (inst->up.peer) { inst->up.peer->obj->ctrl(inst->up.peer, @@ -571,11 +569,11 @@ X25_release_l3(x25_l3_t *l3) { MGR_DISCONNECT | REQUEST, &inst->down); } if (inst->obj) { - REMOVE_FROM_LISTBASE(l3, ((x25_l3_t *)inst->obj->ilist)); + list_del_init(&l3->list); } discard_queue(&l3->downq); - while(l3->channels) - X25_release_channel(l3->channels); + list_for_each_entry_safe(ch, nch, &l3->channellist, list) + X25_release_channel(ch); mISDN_FsmDelTimer(&l3->TR, 3); if (inst->obj) { if (l3->entity != MISDN_ENTITY_NONE) @@ -654,7 +652,7 @@ new_x25_channel(x25_l3_t *l3, x25_channel_t **ch_p, __u16 ch, int dlen, u_char * mISDN_FsmInitTimer(&l3c->x25d, &l3c->TD); skb_queue_head_init(&l3c->dataq); - APPEND_TO_LIST(l3c, l3->channels); + list_add_tail(&l3c->list, &l3->channellist); *ch_p = l3c; return(0); } @@ -671,6 +669,7 @@ new_x25_l3(x25_l3_t **l3_p, mISDNstack_t *st, mISDN_pid_t *pid, mISDNobject_t *o return(-ENOMEM); } memset(n_l3, 0, sizeof(x25_l3_t)); + INIT_LIST_HEAD(&n_l3->channellist); n_l3->entity = MISDN_ENTITY_NONE; n_l3->next_id = 1; spin_lock_init(&n_l3->lock); @@ -706,7 +705,7 @@ new_x25_l3(x25_l3_t **l3_p, mISDNstack_t *st, mISDN_pid_t *pid, mISDNobject_t *o mISDN_FsmInitTimer(&n_l3->x25r, &n_l3->TR); skb_queue_head_init(&n_l3->downq); - APPEND_TO_LIST(n_l3, ((x25_l3_t *)obj->ilist)); + list_add_tail(&n_l3->list, &obj->ilist); err = obj->ctrl(&n_l3->inst, MGR_NEWENTITY | REQUEST, NULL); if (err) { printk(KERN_WARNING "mISDN %s: MGR_NEWENTITY REQUEST failed err(%x)\n", @@ -714,7 +713,7 @@ new_x25_l3(x25_l3_t **l3_p, mISDNstack_t *st, mISDN_pid_t *pid, mISDNobject_t *o } err = obj->ctrl(st, MGR_REGLAYER | INDICATION, &n_l3->inst); if (err) { - REMOVE_FROM_LISTBASE(n_l3, ((x25_l3_t *)obj->ilist)); + list_del(&n_l3->list); kfree(n_l3); n_l3 = NULL; } else { @@ -923,27 +922,25 @@ X25_send_diagnostic(x25_l3_t *l3, struct sk_buff *skb, int err, int channel) x25_channel_t * X25_get_channel(x25_l3_t *l3, __u16 ch) { - x25_channel_t *l3c = l3->channels; + x25_channel_t *l3c; - while(l3c) { + list_for_each_entry(l3c, &l3->channellist, list) { if (l3c->lchan == ch) - break; - l3c = l3c->next; + return(l3c); } - return(l3c); + return(NULL); } x25_channel_t * X25_get_channel4NCCI(x25_l3_t *l3, __u32 addr) { - x25_channel_t *l3c = l3->channels; + x25_channel_t *l3c; - while(l3c) { + list_for_each_entry(l3c, &l3->channellist, list) { if ((l3c->ncci & 0xffff0000) == (addr & 0xffff0000)) - break; - l3c = l3c->next; + return(l3c); } - return(l3c); + return(NULL); } int diff --git a/drivers/isdn/hardware/mISDN/x25_l3.h b/drivers/isdn/hardware/mISDN/x25_l3.h index b9a6040..1870d3d 100644 --- a/drivers/isdn/hardware/mISDN/x25_l3.h +++ b/drivers/isdn/hardware/mISDN/x25_l3.h @@ -47,10 +47,9 @@ struct _x25_ConfQueue { }; struct _x25_l3 { - x25_l3_t *prev; - x25_l3_t *next; + struct list_head list; mISDNinstance_t inst; - x25_channel_t *channels; + struct list_head channellist; struct FsmInst l2l3m; struct FsmInst x25r; struct FsmTimer TR; @@ -70,8 +69,7 @@ struct _x25_l3 { }; struct _x25_channel { - x25_channel_t *prev; - x25_channel_t *next; + struct list_head list; x25_l3_t *l3; struct FsmInst x25p; struct FsmInst x25d; diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h index 4b90f7e..3486868 100644 --- a/include/linux/mISDNif.h +++ b/include/linux/mISDNif.h @@ -596,6 +596,7 @@ typedef struct _Q931_info { #ifdef __KERNEL__ #include +#include #include typedef struct _mISDNobject mISDNobject_t; @@ -635,8 +636,7 @@ typedef struct _mISDN_headext { /* Basic struct of a mISDN component */ struct _mISDNobject { - mISDNobject_t *prev; - mISDNobject_t *next; + struct list_head list; char *name; int id; int refcnt; @@ -644,27 +644,26 @@ struct _mISDNobject { mISDN_pid_t BPROTO; ctrl_func_t *own_ctrl; ctrl_func_t *ctrl; - void *ilist; + struct list_head ilist; struct module *owner; }; /* the interface between two mISDNinstances */ struct _mISDNif { - mISDNif_t *prev; - mISDNif_t *next; + if_func_t *func; + void *fdata; + mISDNif_t *clone; + mISDNif_t *predecessor; int extentions; int stat; mISDNstack_t *st; mISDNinstance_t *owner; mISDNinstance_t *peer; - if_func_t *func; - void *fdata; }; /* a instance of a mISDNobject */ struct _mISDNinstance { - mISDNinstance_t *prev; - mISDNinstance_t *next; + struct list_head list; char name[mISDN_MAX_IDLEN]; int extentions; u_int id; @@ -682,23 +681,21 @@ struct _mISDNinstance { * normally here is only one instance per layer only if the information * will be splitted here are more instances */ struct _mISDNlayer { - mISDNlayer_t *prev; - mISDNlayer_t *next; + struct list_head list; mISDNinstance_t *inst; }; /* the STACK; a (vertical) chain of layers */ struct _mISDNstack { - mISDNstack_t *prev; - mISDNstack_t *next; + struct list_head list; u_int id; u_int extentions; mISDN_pid_t pid; mISDN_stPara_t para; - mISDNlayer_t *lstack; + struct list_head layerlist; mISDNinstance_t *mgr; - mISDNstack_t *child; + struct list_head childlist; }; /* lowlevel read/write struct for the mISDNdevice */ @@ -716,16 +713,15 @@ struct _mISDNport { /* the user interface to handle /dev/mISDN */ struct _mISDNdevice { - mISDNdevice_t *prev; - mISDNdevice_t *next; + struct list_head list; int minor; struct semaphore io_sema; int open_mode; mISDNport_t rport; mISDNport_t wport; - struct _devicelayer *layer; - struct _devicestack *stack; - struct _mISDNtimer *timer; + struct list_head layerlist; + struct list_head stacklist; + struct list_head timerlist; struct list_head entitylist; };