2 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
15 #include <linux/types.h>
16 #include <linux/stddef.h>
17 #include <linux/module.h>
18 #include <linux/spinlock.h>
19 #include <linux/mISDNif.h>
24 MODULE_AUTHOR("Karsten Keil");
25 MODULE_LICENSE("GPL");
26 module_param(debug
, uint
, S_IRUGO
| S_IWUSR
);
28 static LIST_HEAD(devices
);
29 DEFINE_RWLOCK(device_lock
);
30 static u64 device_ids
;
31 #define MAX_DEVICE_ID 63
33 static LIST_HEAD(Bprotocols
);
34 DEFINE_RWLOCK(bp_lock
);
37 *get_mdevice(u_int id
)
39 struct mISDNdevice
*dev
;
41 read_lock(&device_lock
);
42 list_for_each_entry(dev
, &devices
, D
.list
)
44 read_unlock(&device_lock
);
47 read_unlock(&device_lock
);
52 get_mdevice_count(void)
54 struct mISDNdevice
*dev
;
57 read_lock(&device_lock
);
58 list_for_each_entry(dev
, &devices
, D
.list
)
60 read_unlock(&device_lock
);
69 for (i
= 0; i
<= MAX_DEVICE_ID
; i
++)
70 if (!test_and_set_bit(i
, (u_long
*)&device_ids
))
76 mISDN_register_device(struct mISDNdevice
*dev
, char *name
)
81 dev
->id
= get_free_devid();
85 strcpy(dev
->name
, name
);
87 sprintf(dev
->name
, "mISDN%d", dev
->id
);
88 if (debug
& DEBUG_CORE
)
89 printk(KERN_DEBUG
"mISDN_register %s %d\n",
91 err
= create_stack(dev
);
94 write_lock_irqsave(&device_lock
, flags
);
95 list_add_tail(&dev
->D
.list
, &devices
);
96 write_unlock_irqrestore(&device_lock
, flags
);
99 EXPORT_SYMBOL(mISDN_register_device
);
102 mISDN_unregister_device(struct mISDNdevice
*dev
) {
105 if (debug
& DEBUG_CORE
)
106 printk(KERN_DEBUG
"mISDN_unregister %s %d\n",
108 write_lock_irqsave(&device_lock
, flags
);
109 list_del(&dev
->D
.list
);
110 write_unlock_irqrestore(&device_lock
, flags
);
111 test_and_clear_bit(dev
->id
, (u_long
*)&device_ids
);
114 EXPORT_SYMBOL(mISDN_unregister_device
);
117 get_all_Bprotocols(void)
119 struct Bprotocol
*bp
;
123 list_for_each_entry(bp
, &Bprotocols
, list
)
125 read_unlock(&bp_lock
);
130 get_Bprotocol4mask(u_int m
)
132 struct Bprotocol
*bp
;
135 list_for_each_entry(bp
, &Bprotocols
, list
)
136 if (bp
->Bprotocols
& m
) {
137 read_unlock(&bp_lock
);
140 read_unlock(&bp_lock
);
145 get_Bprotocol4id(u_int id
)
149 if (id
< ISDN_P_B_START
|| id
> 63) {
150 printk(KERN_WARNING
"%s id not in range %d\n",
154 m
= 1 << (id
& ISDN_P_B_MASK
);
155 return get_Bprotocol4mask(m
);
159 mISDN_register_Bprotocol(struct Bprotocol
*bp
)
162 struct Bprotocol
*old
;
164 if (debug
& DEBUG_CORE
)
165 printk(KERN_DEBUG
"%s: %s/%x\n", __func__
,
166 bp
->name
, bp
->Bprotocols
);
167 old
= get_Bprotocol4mask(bp
->Bprotocols
);
170 "register duplicate protocol old %s/%x new %s/%x\n",
171 old
->name
, old
->Bprotocols
, bp
->name
, bp
->Bprotocols
);
174 write_lock_irqsave(&bp_lock
, flags
);
175 list_add_tail(&bp
->list
, &Bprotocols
);
176 write_unlock_irqrestore(&bp_lock
, flags
);
179 EXPORT_SYMBOL(mISDN_register_Bprotocol
);
182 mISDN_unregister_Bprotocol(struct Bprotocol
*bp
)
186 if (debug
& DEBUG_CORE
)
187 printk(KERN_DEBUG
"%s: %s/%x\n", __func__
, bp
->name
,
189 write_lock_irqsave(&bp_lock
, flags
);
191 write_unlock_irqrestore(&bp_lock
, flags
);
193 EXPORT_SYMBOL(mISDN_unregister_Bprotocol
);
200 printk(KERN_INFO
"Modular ISDN core version %d.%d.%d\n",
201 MISDN_MAJOR_VERSION
, MISDN_MINOR_VERSION
, MISDN_RELEASE
);
202 mISDN_initstack(&debug
);
203 err
= mISDN_inittimer(&debug
);
206 err
= l1_init(&debug
);
208 mISDN_timer_cleanup();
211 err
= Isdnl2_Init(&debug
);
213 mISDN_timer_cleanup();
217 err
= misdn_sock_init(&debug
);
219 mISDN_timer_cleanup();
227 void mISDN_cleanup(void)
229 misdn_sock_cleanup();
230 mISDN_timer_cleanup();
234 if (!list_empty(&devices
))
235 printk(KERN_ERR
"%s devices still registered\n", __func__
);
237 if (!list_empty(&Bprotocols
))
238 printk(KERN_ERR
"%s Bprotocols still registered\n", __func__
);
239 printk(KERN_DEBUG
"mISDNcore unloaded\n");
242 module_init(mISDNInit
);
243 module_exit(mISDN_cleanup
);