}
static LIST_HEAD(ipc_head);
+static spinlock_t ipc_head_lock;
int
ippp_ccp_set_compressor(struct ippp_ccp *ccp, int unit,
printk(KERN_DEBUG "[%d] Set %scompressor type %d\n", unit,
data->flags & IPPP_COMP_FLAG_XMIT ? "" : "de", num);
+ spin_lock(&ipc_head_lock);
list_for_each_entry(ipc, &ipc_head, list) {
- if (ipc->num != num)
- continue;
-
- if (!try_module_get(ipc->owner))
- continue;
-
- stat = ipc->alloc(data);
- if (!stat) {
- printk(KERN_ERR "Can't alloc (de)compression!\n");
- module_put(ipc->owner);
- break;
- }
- ret = ipc->init(stat, data, unit, 0);
- if(!ret) {
- printk(KERN_ERR "Can't init (de)compression!\n");
- ipc->free(stat);
- module_put(ipc->owner);
- break;
+ if (ipc->num == num &&
+ try_module_get(ipc->owner))
+ goto found;
+ }
+ spin_unlock(&ipc_head_lock);
+ return -EINVAL;
+
+ found:
+ spin_unlock(&ipc_head_lock);
+
+ stat = ipc->alloc(data);
+ if (!stat) {
+ printk(KERN_ERR "Can't alloc (de)compression!\n");
+ goto err;
+ }
+ ret = ipc->init(stat, data, unit, 0);
+ if(!ret) {
+ printk(KERN_ERR "Can't init (de)compression!\n");
+ ipc->free(stat);
+ goto err;
+ }
+ if (data->flags & IPPP_COMP_FLAG_XMIT) {
+ if (ccp->comp_stat) {
+ ccp->compressor->free(ccp->comp_stat);
+ module_put(ccp->compressor->owner);
}
- if (data->flags & IPPP_COMP_FLAG_XMIT) {
- if (ccp->comp_stat) {
- ccp->compressor->free(ccp->comp_stat);
- module_put(ccp->compressor->owner);
- }
ccp->comp_stat = stat;
ccp->compressor = ipc;
- } else {
- if (ccp->decomp_stat) {
- ccp->decompressor->free(ccp->decomp_stat);
- module_put(ccp->decompressor->owner);
- }
- ccp->decomp_stat = stat;
- ccp->decompressor = ipc;
+ } else {
+ if (ccp->decomp_stat) {
+ ccp->decompressor->free(ccp->decomp_stat);
+ module_put(ccp->decompressor->owner);
}
- return 0;
+ ccp->decomp_stat = stat;
+ ccp->decompressor = ipc;
}
+ return 0;
+
+ err:
+ module_put(ipc->owner);
return -EINVAL;
}
int i, j;
memset(protos, 0, sizeof(unsigned long) * 8);
+
+ spin_lock(&ipc_head_lock);
list_for_each_entry(ipc, &ipc_head, list) {
j = ipc->num / (sizeof(long)*8);
i = ipc->num % (sizeof(long)*8);
if (j < 8)
protos[j] |= 1 << i;
}
+ spin_unlock(&ipc_head_lock);
}
int
isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc)
{
+ spin_lock(&ipc_head_lock);
list_add_tail(&ipc->list, &ipc_head);
+ spin_unlock(&ipc_head_lock);
+
return 0;
}
int
isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc)
{
+ spin_lock(&ipc_head_lock);
list_del(&ipc->list);
+ spin_unlock(&ipc_head_lock);
+
return 0;
}