linux层的处理
函数注册:
if (ECNT_REGISTER_SUCCESS != ecnt_register_hook(&phy_api_dispatch_hook_ops) ){
panic("Register hook function failed! %s:%d", __FUNCTION__, __LINE__);
}
int ecnt_register_hook(struct ecnt_hook_ops *reg)^M
{^M
struct ecnt_hook_ops *elem;^M
^M
if(!reg){^M
printk("ecnt_register_hook fail, reg is NULL\n");^M
return ECNT_REGISTER_FAIL;^M
}^M
if((reg->maintype >= ECNT_NUM_MAINTYPE) || (reg->subtype >= ECNT_MAX_SUBTYPE)){^M
printk("ecnt_register_hook fail, maintype = %d, subtype=%d, out of range\n", reg->maintype, reg->subtype);^M
return ECNT_REGISTER_FAIL;^M
}^M
if(reg->list.next!= NULL){^M
printk("ecnt_register_hook fail, %s already registered\n", reg->name);^M
return ECNT_REGISTER_FAIL;^M
}^M
if(hook_id >= 0xFFFFFFFF){^M
printk("ecnt_register_hook fail, hook_id out of range\n");^M
return ECNT_REGISTER_FAIL;^M
}^M
spin_lock(&ecnt_hook_lock);^M
list_for_each_entry(elem, &ecnt_hooks[reg->maintype][reg->subtype], list) {^M
if (reg->priority < elem->priority)^M
break;^M
}^M
reg->hook_id = ++hook_id;^M
reg->info.drop_num = 0;^M
list_add_rcu(®->list, elem->list.prev);^M
spin_unlock(&ecnt_hook_lock);^M
^M
return ECNT_REGISTER_SUCCESS;^M
}^M
EXPORT_SYMBOL(ecnt_register_hook);
函数调用:
static inline int CALL_PON_PHY_ENCT_HOOK(struct xpon_phy_api_data_s * data)
{if(ECNT_HOOK_ERROR == __ECNT_HOOK(ECNT_XPON_PHY, ECNT_XPON_PHY_API, (struct ecnt_data * )data) ){
panic("ECNT_HOOK_ERROR occur with cmd_id:0x%x\n", data->cmd_id);
}if(PHY_NO_API == data->ret){
panic("No such API with type:%d, cmd_id:0x%x\n", data->api_type, data->cmd_id);
}return data->ret;
}
__IMEM ecnt_ret_val __ECNT_HOOK(unsigned int maintype, unsigned int subtype,struct ecnt_data *in_data)^M
{^M
ecnt_ret_val ret;^M
struct ecnt_hook_ops *elem;^M
struct list_head* ptr = &ecnt_hooks[maintype][subtype];^M
^M
if((maintype >= ECNT_NUM_MAINTYPE) || (subtype >= ECNT_MAX_SUBTYPE)){^M
printk("__ECNT_HOOK fail, max maintype %d, max subtype %d\n", ECNT_NUM_MAINTYPE, ECNT_MAX_SUBTYPE);^M
return ECNT_HOOK_ERROR;^M
}^M
if (list_empty(&ecnt_hooks[maintype][subtype])){^M
return ECNT_HOOK_ERROR;^M
}^M
^M
/* We may already have this, but read-locks nest anyway */
rcu_read_lock();
^M
elem = list_entry_rcu(ptr, struct ecnt_hook_ops, list); ^M
/* We may already have this, but read-locks nest anyway */^M
ret = ecnt_iterate(&ecnt_hooks[maintype][subtype], &elem, in_data);^M
rcu_read_unlock();^M
^M
return ret;^M
}^M
EXPORT_SYMBOL(__ECNT_HOOK);
注册格式:
struct ecnt_hook_ops phy_api_dispatch_hook_ops = {
.name = "pon_phy_api_dispatch",
.hookfn = pon_phy_api_dispatch,
.is_execute = 1,
.maintype = ECNT_XPON_PHY,
.subtype = ECNT_XPON_PHY_API,
.priority = 1,
};